加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 03:25:24 所属栏目:百科 来源:网络整理
导读:假设你有这两个类: 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 }; 我想要一个模板函数,它取一个边和一个T,并且根据T,如果类有一个成员T :: a,或者对“T.a1”的引用,则返
假设你有这两个类:
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 };

我想要一个模板函数,它取一个边和一个T,并且根据T,如果类有一个成员T :: a,或者对“T.a1”的引用,则返回对“Ta”或“Tb”的引用.如果类有成员T :: a1,则为“T.b1”.

我的出发点是:

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不存在,如何让编译器跳过第一个模板.

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

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,twoSided.a2))
{ 
  return side == Side::A ? twoSided.a2 : twoSided.b2; 
}

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

解决方法

有了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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读