代码之家  ›  专栏  ›  技术社区  ›  Greg Rogers

静态成员变量在GCC上编译错误的概念检查

  •  3
  • Greg Rogers  · 技术社区  · 14 年前

    我正在尝试应用中描述的技术 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'
    

    我使用GCC4.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 回复  |  直到 14 年前
        1
  •  2
  •   Prasoon Saurav    14 年前