I wrote this code to check if the class type is begin .
struct foo //a simple type to check { int begin(){ return 0;} }; struct Fallback { int begin(){ return 0;} }; template<typename T> struct HasfuncBegin : T,Fallback { typedef char one; typedef int two; template<typename X> static one check(int (X::*)() = &HasfuncBegin<T>::begin); template<typename X> static two check(...); enum :bool {yes = sizeof(check<T>())==1, no= !yes}; }; int main() { std::cout<< HasfuncBegin<foo>::yes; return 0; }
What causes the error:
error: call of overloaded 'check()' is ambiguous enum {yes = sizeof(check<T>())==1, no= !yes}; ^ C:\XXX\main.cpp:24:16: note: candidate: static HasfuncBegin<T>::one HasfuncBegin<T>::check(int (X::*)()) [with X = foo; T = foo; HasfuncBegin<T>::one = char] static one check(int (X::*)() = &HasfuncBegin<T>::begin); ^ C:\XXX\main.cpp:26:16: note: candidate: static HasfuncBegin<T>::two HasfuncBegin<T>::check(...) [with X = foo; T = foo; HasfuncBegin<T>::two = int] static two check(...); ^
Can someone explain why the call is ambiguous (although the first check function with the signature one check(int (X::*)() = &HasfuncBegin<T>::begin); has a default argument to use) and also how to force mine Does the code work ?
Edit:
So here is the final working code:
struct foo { int begin(){ return 0;} }; struct Fallback { int begin(){ return 0;} }; template<typename T, T ptr> struct dummy{}; template<typename T> struct HasfuncBegin : T,Fallback { typedef char one; typedef int two; template<typename X> static one check(dummy<int (X::*)(),&HasfuncBegin<X>::begin>*);
source share