JQ.*_*JQ. 4 c++ member-functions compile-time
可能重复:
是否可以编写C++模板来检查函数是否存在?
说有两个类:
struct A{ int GetInt(){ return 10; } };
struct B{ int m; };
Run Code Online (Sandbox Code Playgroud)
我想在以下函数中使用类型A或B的对象
tempate< typename T >
int GetInt( const T & t )
{
//if it's A, I'll call: return t.GetInt();
//if its' B, I'll call: return t.m;
}
Run Code Online (Sandbox Code Playgroud)
现在,因为有一大堆类,一些包含GetInt(),一些不包含,我不想为每种类型编写特化,我只想在编译时通过' 包含GetInt()来区分它们',我该怎么做?
但在您的特定情况下,您不需要SFINAE,虚拟成员或任何类似的东西.
你只需要一个普通的重载函数.
int GetInt(A& t) { return t.GetInt(); }
int GetInt(const B& t) { return t.m; }
Run Code Online (Sandbox Code Playgroud)
如果需要在不同版本之间共享代码,则重构它以便有一个调用重载内联函数的模板,所有特定于类型的行为都在内联函数中,并且所有共享行为都在模板中.
对于你的"我有很多课程"的需要,SFINAE看起来或多或少会像这样:
template<typename T>
int GetInt(const T& t, int (T::*extra)() const = &T::GetInt)
{
return t.GetInt();
}
template<typename T>
auto GetInt(const T& t) -> decltype(t.m)
{
return t.m;
}
Run Code Online (Sandbox Code Playgroud)
编辑:SFINAE的现实非常丑陋,至少在C++ 0x出现之前.事实上,它开始看起来和GMan的答案一样糟糕.
struct A{ int GetInt() const { return 10; } };
struct B{ int m; };
template<typename T, int (T::*extra)() const>
struct has_mfunc
{
typedef int type;
};
template<typename T>
typename has_mfunc<T, &T::GetInt>::type GetInt(const T& t)
{
return t.GetInt();
}
template<typename T, typename U, U (T::*extra)>
struct has_field
{
typedef U type;
};
template<typename T>
typename has_field<T, int, &T::m>::type GetInt(const T& t)
{
return t.m;
}
int main(void)
{
A a;
B b;
b.m = 5;
return GetInt(a) + GetInt(b);
}
Run Code Online (Sandbox Code Playgroud)
从这里窃取,并假设你修复了你的代码,所以GetInt是 const,我们得到:
HAS_MEM_FUNC(GetInt, has_GetInt);
template <bool B>
struct bool_type
{
static const bool value = B;
};
typedef bool_type<true> true_type;
typedef bool_type<false> false_type;
namespace detail
{
template <typename T>
int get_int(const T& pX, true_type)
{
return pX.GetInt();
}
template <typename T>
int get_int(const T& pX, false_type)
{
return pX.m;
}
}
template <typename T>
int get_int(const T& pX)
{
return detail::get_int(pX,
has_GetInt<T, int (T::*)() const>::value);
}
Run Code Online (Sandbox Code Playgroud)
但这是一个非常糟糕的设计。您应该解决问题而不是应用补丁。