for*_*818 30 c++ implicit-conversion unsigned-integer
假设你有这个:
struct Foo {
Foo(unsigned int x) : x(x) {}
unsigned int x;
};
int main() {
Foo f = Foo(-1); // how to get a compiler error here?
std::cout << f.x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
是否有可能阻止隐式转换?
我能想到的唯一方法是explicilty提供一个构造函数,int如果int是负数,则会产生并产生某种运行时错误,但如果我为此得到编译器错误会更好.
我几乎可以肯定,有一个重复,但我能找到的最接近的是这个问题,而不是为什么允许隐式转换.
我对C++ 11和pre C++ 11解决方案感兴趣,最好是两者兼容.
sky*_*ack 29
统一初始化可防止缩小.
它遵循一个(不工作,如请求)示例:
struct Foo {
explicit Foo(unsigned int x) : x(x) {}
unsigned int x;
};
int main() {
Foo f = Foo{-1};
std::cout << f.x << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
只需尽可能习惯使用统一初始化(Foo{-1}而不是Foo(-1)).
编辑
作为替代方案,根据OP在评论中的要求,与C++ 98一起使用的解决方案是声明为private构造函数获取int(long int,依此类推).
不需要实际定义它们.
请注意,= delete这也是一个很好的解决方案,正如另一个答案中所建议的那样,但是从C++ 11开始也是如此.
编辑2
我想添加一个解决方案,虽然它自C++ 11以来是有效的.
这个想法是基于Voo的建议(请参阅Brian的回复的评论以获得更多细节),并在构造函数的参数上使用SFINAE.
它遵循一个最小的工作示例:
#include<type_traits>
struct S {
template<class T, typename = typename std::enable_if<std::is_unsigned<T>::value>::type>
S(T t) { }
};
int main() {
S s1{42u};
// S s2{42}; // this doesn't work
// S s3{-1}; // this doesn't work
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*ian 26
您可以通过删除不需要的重载来强制编译错误.
Foo(int x) = delete;
Run Code Online (Sandbox Code Playgroud)
如果您希望在每次出现此类代码时收到警告,并且您正在使用GCC,请使用该-Wsign-conversion选项.
foo.cc: In function ‘int main()’:
foo.cc:8:19: warning: negative integer implicitly converted to unsigned type [-Wsign-conversion]
Foo f = Foo(-1); // how to get a compiler error here?
^
Run Code Online (Sandbox Code Playgroud)
如果您想要出错,请使用-Werror=sign-conversion.
| 归档时间: |
|
| 查看次数: |
2889 次 |
| 最近记录: |