根据成员的存在选择模板功能

时间:2017-01-23 17:09:12

标签: c++ templates sfinae

假设你有这两个类:

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 };

我想要一个模板函数,该函数需要sideT,并且根据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

另一种方法是使用逗号运算符和表示每个“概念”的特殊结构

1 个答案:

答案 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; 
}

Demo