我有这个函数用于从极坐标符号中创建一个向量,其中使用了大括号初始值设定项:
// Constructs a 2D vector from XY-coordinates.
inline vector2(float x, float y) : x_(x), y_(y) { }
// Constructs a 2D vector from polar coordinates
static vector2 polar(float r, float phi) {
return {r * cos(phi), r * sin(phi)};
}
在 MSVS 中一切似乎都很好,但 g++ 编译器显示的警告对我来说似乎很奇怪:
vector2.h:37:23: warning: narrowing conversion of ‘(((double)r) * cos(((double)phi)))’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]
return {r * cos(phi), r * sin(phi)};
~~^~~~~~~~~~
如果我使用构造函数警告消失:
// Constructs a 2D vector from polar coordinates
static vector2 polar(float r, float phi) {
return vector2(r * cos(phi), r * sin(phi));
}
为什么会出现此警告?这是否意味着编译后的程序会进行不必要的float
todouble
和 back to转换float
?
更新 这是最小的可重现示例
#include <iostream>
#include <cmath>
using std::cout;
using std::endl;
class Pair {
public:
float x_;
float y_;
inline Pair(float x, float y) : x_(x), y_(y) {};
};
Pair braced(float a) {
return {a * 2, cos(a) * 3};
}
Pair constr(float a) {
return Pair(a * 2, cos(a) * 3);
}
Pair stdbraced(float a) {
return {a * 2, std::cos(a) * 3};
}
Pair stdconstr(float a) {
return Pair(a * 2, std::cos(a) * 3);
}
int main() {
float x = 2.0;
auto a = braced(x);
cout << a.x_ << ' ' << a.y_ << endl;
auto b = constr(x);
cout << b.x_ << ' ' << b.y_ << endl;
auto c = stdbraced(x);
cout << c.x_ << ' ' << c.y_ << endl;
auto d = stdconstr(x);
cout << d.x_ << ' ' << d.y_ << endl;
}
输出g++ test.cpp -o test
:
test.cpp: In function ‘Pair braced(float)’:
test.cpp:15:27: warning: narrowing conversion of ‘(cos(((double)a)) * (double)3)’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]
return {a*2,cos(a)*3};
~~~~~~^~
所以使用std::cos
做帮助。但主要问题仍然存在(并且困扰我) - 为什么警告仅在使用支撑初始化时出现?