根据成员的存在选择模板函数 [英] Choose template function based on existence of member

查看:36
本文介绍了根据成员的存在选择模板函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有这两个类:

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,返回对Ta" 或 "Tb" 如果该类具有成员 T::a,或对 "T.a1 的引用>" 或 "T.b1" 如果类有成员 T::a1.

I want a template function which takes a side and a T, and depending on the T, returns a reference to "T.a" or "T.b" if the class has a member T::a, or a reference to "T.a1" or "T.b1" if the class has a member 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; 
}

问题是如果成员 a 不存在,如何让编译器跳过第一个模板.

The question is how to get the compiler to skip the first template if the member a does not exist.

所以我实现了下面@Jarod42 给出的解决方案,但它在 VS 2015 中给出了错误,因为 VS 区分模板的能力存在错误.这是一个解决方法:

So I implemented the solution given by @Jarod42 below, but it gave errors in VS 2015 because of a bug in VS ability to differentiate between templates. Here is a work around:

template<typename T>
auto GetBySide(const Side &side, const T& twoSided) 
-> decltype((twoSided.a))
{ 
  return side == Side::A ? twoSided.a : twoSided.b; 
}

// Using comma operator to trick compiler so it doesn't think that this is the same as above
template<typename T>
auto GetBySide(const Side &side, const T &twoSided) 
-> decltype((0, twoSided.a1))
{ 
  return side == Side::A ? twoSided.a1 : twoSided.b1; 
}

// See comment above
template<typename T>
auto GetBySide(const Side &side, const T &twoSided) 
-> decltype((0, 0, twoSided.a2))
{ 
  return side == Side::A ? twoSided.a2 : twoSided.b2; 
}

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

Another way would be to use the comma operator and a special struct which represented each "concept"

推荐答案

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

演示

这篇关于根据成员的存在选择模板函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆