gpt4 book ai didi

c++ - 警告 : narrowing conversion C++11

转载 作者:IT老高 更新时间:2023-10-28 22:26:45 24 4
gpt4 key购买 nike

g++ 4.9.0-O2 -std=c++11

template<class T>
struct vec3 {
T x, y, z;
vec3() = default;
vec3(const vec3<T> &other) = default;
vec3(T xx, T yy, T zz) { x = xx; y = yy; z = zz; }
vec3<T> operator-(const vec3<T> &other) {
return vec3<T>{ x - other.x, y - other.y, z - other.z };
}
};

int main() {
vec3<char> pos{ 0, 0, 0 };
vec3<char> newPos{ 0, 0, 0 };
auto p = pos - newPos;

return 0;
}

我收到警告:

!!warning: narrowing conversion of ‘(((int)((vec3<char>*)this)->vec3<char>::x) - ((int)other.vec3<char>::x))’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]

但如果我在 operator- 函数中使用 (...) 插入 {...} ,则警告会消失.为什么?

最佳答案

首先,为什么要缩小?这来自§5/10:

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

— [..]

— Otherwise, the integral promotions (4.5) shall be performed on both operands.

积分提升在 4.5/1 中定义:

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

在我们的例子中,我们有 decltype(char + char)int因为char的转化排名低于 int所以两者都被提升为int在调用 operator+ 之前.现在,我们有 int s 我们将传递给一个构造函数,该构造函数采用 char s。根据定义(§8.5.4/7,特别是 7.4):

A narrowing conversion is an implicit conversion

(7.4) — from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.

根据 §8.5.4/3 在列表初始化中明确禁止(强调我的,“见下文”实际上是指我刚刚在上面复制的内容):

List-initialization of an object or reference of type T is defined as follows

— [..]

— Otherwise, if T is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution (13.3, 13.3.1.7). If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed. [...]

这就是为什么您的 vec3<T>{int, int, int}给你一个警告:由于整数提升需要对所有表达式进行缩小转换,程序格式错误。现在,关于“格式错误”的陈述仅在列表初始化的上下文中出现。这就是为什么如果您在没有 {}s 的情况下初始化 vector 的原因。 ,您看不到该警告:

vec3<T> operator-(const vec3<T> &other) { 
// totally OK: implicit conversion from int --> char is allowed here
return vec3<T>( x - other.x, y - other.y, z - other.z );
}

至于解决这个问题——只调用没有列表初始化的构造函数可能是最简单的解决方案。或者,您可以继续使用列表初始化并仅模板化您的构造函数:

template <typename A, typename B, typename C>
vec3(A xx, B yy, C zz)
: x(xx) // note these all have to be ()s and not {}s for the same reason
, y(yy)
, z(yy)
{ }

关于c++ - 警告 : narrowing conversion C++11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27844971/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com