Проверка концепции статической переменной-члена при компиляции ошибки на gcc - PullRequest
3 голосов
/ 24 октября 2010

Я пытаюсь применить технику, описанную в http://www.drdobbs.com/tools/227500449

С примером кода ниже, я ожидаю, что вывод:

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

И это действительно то, что происходит, если я компилирую с использованием clang. Но с gcc этот код выдает следующие ошибки:

junk.cpp: In instantiation of ‘const bool has_foo_member_variable<B>::value’:
junk.cpp:45:5:   instantiated from ‘void print() [with T = B]’
junk.cpp:82:14:   instantiated from here
junk.cpp:30:75: error: ‘B::foo’ is not a valid template argument for type ‘int B::*’
junk.cpp:30:75: error: it must be a pointer-to-member of the form `&X::Y'
junk.cpp: In instantiation of ‘const bool has_foo_member_variable<D>::value’:
junk.cpp:45:5:   instantiated from ‘void print() [with T = D]’
junk.cpp:84:14:   instantiated from here
junk.cpp:30:75: error: ‘& D::foo’ is not a valid template argument for type ‘int D::*’
junk.cpp:30:75: error: it must be a pointer-to-member of the form `&X::Y'

Я использую gcc 4.5.1 ... Похоже, что gcc не следует правильным правилам SFINAE, но я не уверен на 100%. Является ли Clang правильным, и это ошибка GCC?

#include <iostream>

struct small_type { char dummy; };
struct large_type { char dummy[2]; };

template<class T>
struct has_foo_member_function
{
    template<int (T::*)()> struct tester;
    template<class U> static small_type has_foo(tester<&U::foo> *);
    template<class U> static large_type has_foo(...);
    static const bool value = (sizeof(has_foo<T>(0)) == sizeof(small_type));
};

template<class T>
struct has_foo_static_member_function
{
    template<int (*)()> struct tester;
    template<class U> static small_type has_foo(tester<&U::foo> *);
    template<class U> static large_type has_foo(...);
    static const bool value = (sizeof(has_foo<T>(0)) == sizeof(small_type));
};

template<class T>
struct has_foo_member_variable
{
    template<int T::*> struct tester;
    template<class U> static small_type has_foo(tester<&U::foo> *);
    template<class U> static large_type has_foo(...);
    static const bool value = (sizeof(has_foo<T>(0)) == sizeof(small_type));
};

template<class T>
struct has_foo_static_member_variable
{
    template<int *> struct tester;
    template<class U> static small_type has_foo(tester<&U::foo> *);
    template<class U> static large_type has_foo(...);
    static const bool value = (sizeof(has_foo<T>(0)) == sizeof(small_type));
};

template<class T>
void print()
{
    std::cout << has_foo_member_function<T>::value << " "
        << has_foo_static_member_function<T>::value << " "
        << has_foo_member_variable<T>::value << " "
        << has_foo_static_member_variable<T>::value << "\n";
}

struct A
{
    int foo()
    {
        return 0;
    }
};

struct B
{
    static int foo()
    {
        return 0;
    }
};

struct C
{
    int foo;
};

struct D
{
    static int foo;
};

int main()
{
    print<A>();
    print<B>();
    print<C>();
    print<D>();
}

1 Ответ

2 голосов
/ 24 октября 2010

Ваш код правильный .

Корректен ли лязг, и это ошибка gcc? Comeau подтверждает, что ваш код правильный.

...