繁体   English   中英

C ++ /模板:是否可以在编译时有选择地禁用类的功能?

[英]C++/templates: Can I selectively disable a function of a class at compile time?

我需要为基本只包含4个数字类型T的四元数类编写2个构造函数。 我有2个构造函数在编译时发生冲突(见下文)。 如果我想调用需要4个整数的构造函数,是否可以告诉编译器从迭代器中忽略该构造函数(我的尝试已被注释掉-似乎编译器将我的尝试视为实例化整个类的全部或全部)。 (clang)编译器抱怨是“模棱两可的转换”,在尝试执行Quaternion<float> x(1);时,它列出了这两个构造函数Quaternion<float> x(1);

经过我的评论尝试,c告诉我:

error: no type named 'value_type' in 'std::__1::iterator_traits<float>'
      typename std::enable_if<!std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type>

编码:

template <typename T>
class Quaternion {
  public:
   template<typename T1>
   Quaternion(T1 a = 0, T1 b = 0, T1 c = 0, T1 d = 0)
   : _a(static_cast<T>(a)),
     _b(static_cast<T>(b)),
     _c(static_cast<T>(c)),
     _d(static_cast<T>(d)) { }

   template <typename It>
   //typename std::enable_if<!std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type>
   Quaternion(It it)
   : _a(static_cast<T>(++it)),
     _b(static_cast<T>(++it)),
     _c(static_cast<T>(++it)),
     _d(static_cast<T>(++it))
   {}

  private:
    T _a, _b, _c, _d;
};

您可以定义一个自定义特征is_iterator

template<typename T, typename = void>
struct is_iterator {
   static bool const value = false;
};

template<typename T>
struct is_iterator<T, typename std::enable_if<!std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type> {
   static bool const value = true;
};

然后SFINAE通过以下方式使用默认的模板参数输出构造函数:

template<typename T1, typename = typename std::enable_if<!is_iterator<T1>::value>::type>
Quaternion(T1 a = 0, T1 b = 0, T1 c = 0, T1 d = 0)
:_a(static_cast<T>(a)),
 _b(static_cast<T>(b)),
 _c(static_cast<T>(c)),
 _d(static_cast<T>(d)) 
 {}

template <typename It, typename = typename std::enable_if<is_iterator<It>::value>::type>
Quaternion(It it)
:_a(static_cast<T>(*(++it))),
 _b(static_cast<T>(*(++it))),
 _c(static_cast<T>(*(++it))),
 _d(static_cast<T>(*(++it)))
{}

现场演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM