C ++模板 - 仅当模板参数中的某个值时才添加函数

时间:2015-12-20 13:19:24

标签: c++ templates c++11

我在这里尝试的方式是否可行?

我知道#if不能处理模板参数。

请不要教我如何反对C ++的概念,这不是问题所在。

typedef enum {
kPropertyReadWrite,
kPropertyReadOnly
} PropertyType;


template <typename T, PropertyType P = kPropertyReadWrite>
class property {
  T value;
public:
  property() {}
  property(T initValue) : value(initValue){}


#if P == kPropertyReadOnly
  T & operator = (const T &i) {
    //::std::cout << i << ::std::endl;

    return value = i;
  }
#endif

  operator T const & () const {
    return value;
  }
};

3 个答案:

答案 0 :(得分:3)

我很惊讶很多人都无法获得SFINAE的权利。 SFINAE条件需要依赖于operator=的模板参数,而不是类模板。否则,实例化类模板可能会导致硬错误。

template<PropertyType P1 = P, typename std::enable_if<P1 != kPropertyReadOnly, int>::type = 0>
T & operator = (const T &i) {
  //::std::cout << i << ::std::endl;

  return value = i;
}

请注意,这实际上不足以阻止property<int, kPropertyReadOnly> p2; p2 = 10;编译,因为您的代码定义了从Tproperty<T, ...>的隐式转换,因此编译器将隐式转换{{1} }到10,然后调用复制赋值运算符。

答案 1 :(得分:2)

这可以通过std::enable_if

轻松实现
template<PropertyType U = P, typename std::enable_if<P == kPropertyReadWrite, int>::type = 0> T& operator=(const T &i)
{ 
  return value = i;
}

This通过在编译期间不满足条件时禁用该方法,在这种情况下引发编译错误(或在不同场景中选择另一个启用的实现)

答案 2 :(得分:1)

您可以提供模板专业化:

typedef enum {
kPropertyReadWrite,
kPropertyReadOnly
} PropertyType;

template <typename T, PropertyType = kPropertyReadWrite>
class property {
  T value;
public:
  property() {}
  property(T initValue) : value(initValue){}

  operator T const & () const {
    return value;
  }
};

template <typename T>
class property<T, kPropertyReadOnly> {
  T value;
public:
  property() {}
  property(T initValue) : value(initValue){}

  T & operator = (const T &i) {
    std::cout << i << ::std::endl;
    return value = i;
  }

  operator T const & () const {
    return value;
  }
};

Live Demo