我们如何告诉C ++编译器在使用+
和/
等算术运算符时应该避免隐式转换,即
size_t st_1, st_2;
int i_1, i_2;
auto st = st_1 + st_2; // should compile
auto i = i_1 + i_2; // should compile
auto error_1 = st_1 + i_2; // should not compile
auto error_2 = i_1 + st_2; // should not compile
// ...
答案 0 :(得分:4)
不幸的是,该语言指定了向int
添加size_t
时会发生什么(请参阅其类型提升规则),因此您无法强制编译时错误。
但您可以构建自己的add
函数来强制参数类型相同:
template <class Y>
Y add(const Y& arg1, const Y& arg2)
{
return arg1 + arg2;
}
常量引用阻止任何类型转换,模板强制两个参数都是相同的类型。
由于size_t
必须为unsigned
类型,因此总是在您的特定情况下工作:
答案 1 :(得分:1)
对于内置(非类)类型,无法阻止不需要的隐式类型转换。
某些编译器可以配置为针对涉及可疑转换的操作发出警告,但这并未涵盖所有可能的隐式转换(毕竟,从short
到long
的转换是保留值,因此不是所有编译器都会将其报告为可疑的)。其中一些编译也可能被配置为在发出警告时给出错误。
使用C ++类类型,可以通过构造构造函数explicit
来防止隐式转换,而不是定义转换运算符(例如,名为operator int()
的类成员函数)。
类类型也可以提供数字运算符(operator+()
等),它只接受所需类型的操作数。问题是,这并不一定会阻止参与此类表达式的内置类型的推广。例如,提供operator+(int) const
(因此some_object = some_other_object + some_int
将起作用)的类不会阻止编译some_other_object + some_short
这样的表达式(因为some_short
可以隐式提升为{{ 1}})。
这基本上意味着可以防止对类类型的隐式转换,但不能阻止使用数字运算符在表达式中进行促销。
答案 2 :(得分:1)
我能给你的最佳答案是使用单位:看看boost unit。
另一个有趣的方法是使用opaque typedef
你可以看一下这篇论文Toward Opaque Typedef here一个非常有趣的谈话和实现。
希望材料有用