This code compiles with g++ 4.7.3, clang 3.2, but not g++ 4.8. Error is: In substitution of ‘template<class C> static constexpr int has<T>::test(decltype (sizeof (C:: x))) [with C = C; T = foo] [with C = foo]’: required from ‘const int foobar<foo>::value’ required from here error: invalid use of non-static member function ‘int foo::x()’ #include <string> #include <iostream> template <typename T> struct has { template <typename> constexpr static int test(...) { return 0; } template <typename C> constexpr static int test(decltype(sizeof(C::x))) { // Doesn't compile. return 1; // Is a member variable. } template <typename C, int c = sizeof(decltype(((C*)nullptr)->x()))> constexpr static int test(int) { return 2; // Is a member function. } static const int value = test<T>(0); }; struct foo { int x(); }; struct bar { int x; }; int main() { std::cout << has<int>::value << std::endl; std::cout << has<foo>::value << std::endl; std::cout << has<bar>::value << std::endl; }
Started with http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190830 By using __builtin_printf or static_assert one can avoid all the includes.
Seems simple: missing propagation of complain.
Fixed mainline and 4.8.1.