假设你有这两个类:
class A
{
public:
int a;
int b;
}
class B
{
public:
int a;
int b;
}
class C
{
public:
float a1;
float b1;
}
enum class Side { A, B };
我想要一个模板函数,该函数需要side
和T
,并且根据T
,返回对“T.a
”或“{{1”的引用如果类有成员T.b
,或者如果该类有成员T::a
,则引用“T.a1
”或“T.b1
”。
我的出发点是:
T::a1
问题是如果成员template<typename T>
auto &GetBySide(const Side &side, const T &twoSided)
{
return side == Side::A?twoSided.a:twoSided.b;
}
template<typename T>
auto &GetBySide(const Side &side, const T &twoSided)
{
return side == Side::A?twoSided.a1:twoSided.b1;
}
不存在,如何让编译器跳过第一个模板。
所以我实现了下面@ Jarod42给出的解决方案,但由于VS能够区分模板的错误,它在VS 2015中给出了错误。这是一个解决方法:
a
另一种方法是使用逗号运算符和表示每个“概念”的特殊结构
答案 0 :(得分:11)
使用SFINAE。
template<typename T>
auto GetBySide(const Side &side, const T& twoSided)
-> decltype((twoSided.a))
{
return side == Side::A ? twoSided.a : twoSided.b;
}
template<typename T>
auto GetBySide(const Side &side, const T &twoSided)
-> decltype((twoSided.a1))
{
return side == Side::A ? twoSided.a1 : twoSided.b1;
}