Я написал этот код, чтобы проверить, есть ли тип класса 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;
}
Который производит ошибку:
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(...);
^
Может кто-нибудь, пожалуйста, объясните, почему вызов неоднозначен (даже если первая функция проверки с подписью one check(int (X::*)() = &HasfuncBegin<T>::begin);
имеет аргумент по умолчанию будет использоваться) и также, как сделать свой код работа?
Edit:
Так вот окончательный рабочий код:
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>*);
// even this won't work, so replace above statement with below commented one
// static one check(dummy<decltype(&HasfuncBegin<X>::begin),&HasfuncBegin<X>::begin>*);
template<typename X>
static two check(...);
enum {yes = sizeof(check<T>(0))==1, no= !yes};
};
Почему бы не использовать что-то вроде 'имяТипа станд :: условно :: значение, один, два> :: type'? –
Аргументы функции по умолчанию не являются частью сигнатуры функции и не рассматриваются SFINAE. – cpplearner
Возможный дубликат http://stackoverflow.com/q/257288/1639256 или http://stackoverflow.com/q/1966362/1639256 – Oktalist