使用算术运算符时禁止隐式转换
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)类型,无法阻止不需要的隐式类型转换。
一些编译器可以配置为对涉及可疑转换的操作发出警告,但这并不涵盖所有可能的隐式转换(毕竟,从 short
到 long
的转换是保值的,所以并不是所有的编译器都会将其报告为可疑)。其中一些编译也可能被配置为在发出警告的地方给出错误。
对于 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有用
我们如何告诉 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)类型,无法阻止不需要的隐式类型转换。
一些编译器可以配置为对涉及可疑转换的操作发出警告,但这并不涵盖所有可能的隐式转换(毕竟,从 short
到 long
的转换是保值的,所以并不是所有的编译器都会将其报告为可疑)。其中一些编译也可能被配置为在发出警告的地方给出错误。
对于 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有用