将运算符类型转换为除某些引用之外的任何算术类型
Type cast operators to any arithmetic type except some reference
假设我们有这样一个例子class:
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 类型除外。对于给定的示例,编译器通知存在多个转换。如何处理这样的问题?有可能吗?
问题是is_arithmetic<T>
。它没有你想象的那样。那是一个模板非类型参数。 is_arithmetic
是一个class,一个类型。
可以这样想:
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 {
我对你的设计也有一些担忧。根据经验,隐式转换是不好的。所以你至少可以让它们明确。
我想出了一个解决方案,比如实现给定的运算符:
operator int&();
operator float&();
operator T();
operator T() const;
使用这组运算符,我能够像我预期的那样定义算术变量,即非常量、常量、常量引用和特定类型(如 int 和 float)的额外引用。
假设我们有这样一个例子class:
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 类型除外。对于给定的示例,编译器通知存在多个转换。如何处理这样的问题?有可能吗?
问题是is_arithmetic<T>
。它没有你想象的那样。那是一个模板非类型参数。 is_arithmetic
是一个class,一个类型。
可以这样想:
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 {
我对你的设计也有一些担忧。根据经验,隐式转换是不好的。所以你至少可以让它们明确。
我想出了一个解决方案,比如实现给定的运算符:
operator int&();
operator float&();
operator T();
operator T() const;
使用这组运算符,我能够像我预期的那样定义算术变量,即非常量、常量、常量引用和特定类型(如 int 和 float)的额外引用。