将运算符类型转换为除某些引用之外的任何算术类型
Type cast operators to any arithmetic type except some reference
假设我们有这样一个示例类:
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
是一个类,一个类型。
这样想:
template <class T, int N>
struct X {};
您也可以省略参数名称:
template <class T, int>
struct X {};
现在有了is_arithmetic<T>
而不是int
。
去掉它,它就起作用了:
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等特定类型的额外引用。
相关文章:
- std::map 保存任何值类型
- 是否允许调用方对我的 Builder 类使用任何指针类型(包括智能指针)?
- 有没有办法在函数 c++ 中输入任何数据类型?
- 如何实现一个接受任何容器类型的函数
- 整数文本太大,无法用任何整数类型表示--C++
- 任何指针类型的模板专业化
- 使用模板C++任何集合类型的包装器
- C 通用函数以除以任何数据类型
- 声明类型没有任何可变类型
- 查找树(不属于任何特定类型的简单连接树)中两个节点之间的路径
- 在任何类类型上使用模板方法中的 new
- C++任何非类型参数的模板专用化
- 是否有任何数据类型或方法可以计算当前单元格中先前数组单元格的总和
- 将任何数据类型/对象作为参数传递以确定其大小
- 任何返回类型的可变参数函数包装器
- 是否要确保一个线程修改的任何数据类型的共享变量对其他线程可见
- 难以创建可以容纳任何数据类型的模板通用向量
- STD ::变体与STD ::任何当类型移动时可构造时
- wchar_t保证与任何整数类型不同
- 将运算符类型转换为除某些引用之外的任何算术类型