c++ - Ambiguous call in custom member detector -
i working in own implementation of member detector improve programming skills. following code compile g++ clang++ reject code, error :
error: call 'check' ambiguous main.cpp:19:17: note: candidate function [with u = has_member::hasit]
static char check( decltype(u::i)* );
main.cpp:22:16: note: candidate function [with u = has_member::hasit]
static int check(u*);
here's code of class
template<typename t> struct has_member { struct fallback { int i; }; struct hasit : fallback, t {}; template<class u> static char check( decltype(u::i)* ); template<typename u> static int check(u*); static const bool value = sizeof(check<hasit>( nullptr ) ) == sizeof(int); }; class test { public: }; int main() { auto v = has_member<test>::value; std::cout << std::boolalpha << v; } live example here
the question : code valid ? if why g++ accepts ?
the code should valid. have 2 viable candidates:
template <class u> static char check( decltype(u::i)* ); // --> int* template <class u> static int check( u* ); // --> hasit* nullptr convertible both pointer types, neither conversion better other, both candidates function templates. former more specialized latter, should preferred. clang bug.
a simple workaround works both compilers change second overload instead be:
template<typename u> static int check(...); since preferred on ellipses, still remains fallback option, without having rely on template partial ordering rules.
furthermore, since we're in c++11, can use return types directly:
template<class u> static std::false_type check( decltype(u::i)* ); template<typename u> static std::true_type check(...); using type = decltype(check<hasit>(nullptr)); static constexpr bool value = type::value;
Comments
Post a Comment