使用算术运算符时禁止隐式转换

时间:2016-11-09 09:14:13

标签: c++ implicit-conversion arithmetic-expressions

我们如何告诉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
// ...

3 个答案:

答案 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)

对于内置(非类)类型,无法阻止不需要的隐式类型转换。

某些编译器可以配置为针对涉及可疑转换的操作发出警告,但这并未涵盖所有可能的隐式转换(毕竟,从shortlong的转换是保留值,因此不是所有编译器都会将其报告为可疑的)。其中一些编译也可能被配置为在发出警告时给出错误。

使用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一个非常有趣的谈话和实现。

希望材料有用