强制缩小转换警告
Force narrowing conversion warning
考虑下面的代码,它演示了一些缩窄转换:
template <class T>
class wrapper
{
template <class> friend class wrapper;
public:
constexpr wrapper(T value)
: _data(value)
{}
template <class U>
constexpr wrapper(wrapper<U> other)
: _data(other._data)
{}
wrapper& operator=(T value)
{_data = value; return *this;}
template <class U>
wrapper& operator=(wrapper<U> other)
{_data = other._data; return *this;}
private:
T _data;
};
int main(int argc, char* argv[])
{
wrapper<unsigned char> wrapper1 = 5U;
wrapper<unsigned char> wrapper2{5U};
wrapper<unsigned char> wrapper3(5U);
wrapper<unsigned int> wrapper4 = 5U;
wrapper<unsigned int> wrapper5{5U};
wrapper<unsigned int> wrapper6(5U);
wrapper<unsigned char> wrapper7 = wrapper4; // Narrowing
wrapper<unsigned char> wrapper8{wrapper5}; // Narrowing
wrapper<unsigned char> wrapper9(wrapper6); // Narrowing
wrapper7 = wrapper4; // Narrowing
wrapper8 = wrapper5; // Narrowing
wrapper9 = wrapper6; // Narrowing
return 0;
}
如何改变wrapper
成员的体,使其触发编译器对窄化转换的警告?我的目标是让用户意识到他们的代码可能有问题。
您可以使用统一的初始化语法触发窄化转换警告:
class wrapper
{
template <class> friend class wrapper;
public:
constexpr wrapper(T value)
: _data{value}
{}
template <class U>
constexpr wrapper(wrapper<U> other)
: _data{other._data} // note the curly brackets here
{}
wrapper& operator=(T value)
{_data = value; return *this;}
template <class U>
wrapper& operator=(wrapper<U> other)
{_data = {other._data}; return *this;} // and here
private:
T _data;
};
wrapper<unsigned int> wrapper1 = 5U;
wrapper<unsigned char> wrapper2 = wrapper1; // Narrowing
wrapper<unsigned char> wrapper3(wrapper1); // Narrowing
wrapper<unsigned char> wrapper4{wrapper1}; // Narrowing
wrapper2 = wrapper1; // Narrowing
最后四行中的任何一行都将在g++中产生窄化转换警告,并在clang中产生窄化转换的编译错误。
要在窄调用中停止编译,可以在
上使用SFINAEtemplate <class U>
constexpr wrapper(wrapper<U> other)
: _data(other._data)
{}
改成
template <class U, typename std::enable_if<sizeof(T) >= sizeof(U)>::type* = nullptr>
constexpr wrapper(wrapper<U> other)
: _data(other._data)
{}
<<p> 生活例子/kbd> 如果要复制的基础类型的大小大于要初始化的对象的基础类型,则将停止编译。
我推荐另一种方法。您不需要篡改代码。当您使用g++进行编译时,请添加-Wconversion标志。
相关文章:
- 获取隐式转换溢出从无符号到已签名的警告
- 奇怪的缩小转换在 g++ 编译器中加倍到浮点警告
- 隐式重新解释引用时强制转换,没有警告/错误
- 将无符号转换为复杂<int>原因符号转换警告
- 如何解决隐式转换丢失整数精度:'size_t'(又名"无符号长")到'int'警告?
- MSVC 中从 _Ty 警告到 int 警告的转换累积
- 为什么在 c++ 中索引字符串会发出隐式转换警告?
- 从 int 中剥离位时,编译器会警告一个转换,但不警告其他转换.有解决方法吗?
- C++:禁用隐式转换警告
- 为什么 gcc 警告只针对统一初始化缩小转换范围?
- 警告 C4267"参数":从"size_t"转换为"DWORD&quo
- 隐式转换:以下警告是否有效?
- 意外 (IMO) 常量转换警告
- C++:禁用 CMake 中的旧样式转换警告
- 键入从 DWORD 到 64 位指针的强制转换警告
- 警告 C4267"正在初始化":从'size_t'转换为"DWORD",可能会丢失数据
- isspace 函数的性能警告,从 int 转换为布尔值
- 隐式转换警告 int 到 int-looklike
- 编译器警告转换
- 将警告转换为错误