假设您有:
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;
}
是否可以防止隐式转换?
我能想到的唯一方法是明确提供一个构造函数,int
如果的int
值为负数,则该构造函数将采用并生成某种运行时错误,但如果能为此得到编译器错误,那就更好了。
我几乎可以肯定,有一个重复项,但是我能找到的最接近的是这个问题,而是问为什么允许隐式转换。
我对C ++ 11和C ++ 11之前的解决方案都感兴趣,最好是对两者都适用的解决方案。
统一的初始化可防止变窄。
它遵循一个(未按要求运行)示例:
struct Foo {
explicit Foo(unsigned int x) : x(x) {}
unsigned int x;
};
int main() {
Foo f = Foo{-1};
std::cout << f.x << std::endl;
}
只需尽可能地习惯使用统一初始化(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
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句