【发布时间】:2015-12-26 12:59:33
【问题描述】:
我编写了这段代码来检查一个类类型是否有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); 有默认参数要使用)以及如何让我的代码工作?
编辑:
所以这是最终的工作代码:
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};
};
【问题讨论】:
-
为什么不使用
typename std::conditional<std::is_same<decltype(&X::begin),int (X::*)()>::value, one, two>::type之类的东西? -
默认函数参数不是函数签名的一部分,SFINAE 不考虑。
-
另外你没有做 SFINAE 因为没有模板参数被推导出来