假设我们有这样一个示例类:
class Union {
union Value {
int i;
float f;
};
enum class Type {
Int, Float
};
Type type;
Value value;
public:
operator int&() { return value.i; }
operator float&() { return value.f; }
template <typename T, is_arithmetic<T>>
operator T() const {
if (type == Type::Int)
return static_cast<T>(value.i);
else
return static_cast<T>(value.f);
}
}
我想允许将Union实例转换为任何算术类型,但禁止将其转换为引用,除了示例中的int和float类型之外。对于给定的示例,编译器会通知有关现有的多个转换。如何处理这样的问题?它甚至可能吗?
答案 0 :(得分:1)
问题是is_arithmetic<T>
。它不是你认为它做的。这是一个模板非类型参数。 is_arithmetic
是一个类,一个类型。
这样想:
template <class T, int N>
struct X {};
您还可以省略参数名称:
template <class T, int>
struct X {};
现在取代int
而不是is_arithmetic<T>
。
摆脱它并且它有效:
template <typename T>
operator T() const {
我的意见是,您不需要确保T
是算术类型,因为static_cast
会为您做到这一点。
如果你想在声明中强制执行,你需要SFINAE和enable_if
,直到我们有概念:
template <class T, class Enable = std::enable_if_t<std::is_arithmetic<T>::value>>
operator T() const {
我对你的设计也有一些顾虑。根据经验,隐式演员是不好的。所以你至少可以把它们弄清楚。
答案 1 :(得分:0)
我想出了一个像实现给定运算符的解决方案:
operator int&();
operator float&();
operator T();
operator T() const;
使用这组运算符,我能够像我期望的那样定义算术变量,即非const,const,const引用和特定类型的额外引用,如int和float。