我在这里尝试的方式是否可行?
我知道#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;
}
};
答案 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;
编译,因为您的代码定义了从T
到property<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;
}
};