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

Inhibit implicit conversion while using arithmetic operators

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

不幸的是,该语言指定了将 int 添加到 size_t 时应该发生的情况(请参阅其类型提升规则),因此您不能强制出现编译时错误。

但您可以构建自己的 add 函数来强制参数为同一类型:

template <class Y>
Y add(const Y& arg1, const Y& arg2)
{
    return arg1 + arg2;
}

常量引用阻止任何类型转换,模板强制两个参数为同一类型。

这将始终适用于您的特定情况,因为size_t必须unsigned类型:

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

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

对于 C++ class 类型,可以通过构造函数 explicit 而不定义转换运算符(例如,名为 class 的成员函数来防止隐式转换13=]).

class 类型也可以提供数字运算符(operator+() 等),它只接受所需类型的操作数。问题是这并不一定会阻止提升参与此类表达式的内置类型。例如,提供 operator+(int) const 的 class(因此 some_object = some_other_object + some_int 可以工作)不会阻止像 some_other_object + some_short 这样的表达式编译(因为 some_short 可以隐式晋升为 int).

这基本上意味着可以防止隐式转换为 class 类型,但不能防止在带有数字运算符的表达式中发生提升。

我能给你的最佳答案是使用单位:看看 boost unit

另一个有趣的方法是使用opaque typedef你可以看看这篇论文Toward Opaque Typedef here一个非常有趣的演讲和实现。

希望material有用