Comprobación de conceptos de errores de compilación de variables miembro estáticas en gcc
Pregunta
Estoy tratando de aplicar la técnica descrita en http://www.drdobbs.com/tools/227500449
Con el código de muestra a continuación, espero el resultado:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Y esto es lo que sucede si compilo usando clang.Pero con gcc, este código genera los siguientes errores:
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'
Estoy usando gcc 4.5.1...Parece que gcc no sigue las reglas correctas de SFINAE, pero no estoy 100% seguro.¿Es clang correcto y se trata de un error de 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>();
}
Solución
Tu código es correcto.
¿Es clang correcto y se trata de un error de gcc?
Sí muy probablemente. Comeau confirma que su código es correcto.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow