将所有浮点文字声明为 double 会在 C++ 中导致真正的问题吗?
Are there any real life situations where declaring all floating point literals as double causes real problems in C++?
意思是,在“正常”情况下,类型提升的性能损失无关紧要,没有人检查浮点数是否相等,也没有人声明任何有趣的东西,比如
void f(float x) {/*do something*/};
void f(double x) {/*do something completely different*/};
等等。
我知道“C++ f 后缀为什么?”的一般问题。已被问过一千次,但所有的答案总是关于技术细节和人为的例子。我还没有找到任何令人满意的答案来显示实际相关的情况,其中区别很重要。
我手头没有一个很好的“现实生活中”的例子。相反,我想尝试用一个简单的例子来说服你。
让我们假设所有函数都为 float
和 double
重载做“正确的事”:
void f(float x) {/*do something*/};
void f(double x) {/*do the same thing*/};
此外,当只有一个重载可用时,我们可以使用任一类型的文字来调用它:
void f_float(float x) {/*do something*/};
void f_double(double x) {/*do the same thing*/};
f_float(3.0); // ok
f_float(3.0f); // ok
f_double(3.0); // ok
f_double(3.0f); // ok
float
s 转换为 double
s,反之亦然。
如果所有代码都可以使用 float
或 double
,那么故事就此结束。但是,您不需要做一些“有趣”的事情来破解代码。
I haven't found any satisfactory answer that shows an actually relevant situation, where the distinction is important.
当文字的类型用于推断其他事物的类型时,这种区别很重要。能够在 double
和 float
之间转换并不是您需要能够用 double
文字替换任何 float
文字而不破坏代码的全部。
在上面的示例中,f_float
可以用 3.0
或 3.0f
调用。现在假设您有一个只接受 std::vector<float>
:
的函数
void bar(const std::vector<float>& x){}
以及给定单个值的东西构造一个向量:
template <typename T>
std::vector<T> make_vect(const T& t){ return {T{}}; }
然后文字的类型使代码要么失败要么通过:
bar(make_vect(0.3f));
//bar(x.make_vect(0.3)); // ERROR
TL;DR
整点只是你可以在float
和double
之间转换,但一般来说some_template<float>
和some_template<double>
之间没有可用的转换。文字的类型可能是相关的,即使您不介意 float
和 double
之间的转换。将 3.0f
更改为 3.0
可以使代码中断,否则没问题
意思是,在“正常”情况下,类型提升的性能损失无关紧要,没有人检查浮点数是否相等,也没有人声明任何有趣的东西,比如
void f(float x) {/*do something*/};
void f(double x) {/*do something completely different*/};
等等。
我知道“C++ f 后缀为什么?”的一般问题。已被问过一千次,但所有的答案总是关于技术细节和人为的例子。我还没有找到任何令人满意的答案来显示实际相关的情况,其中区别很重要。
我手头没有一个很好的“现实生活中”的例子。相反,我想尝试用一个简单的例子来说服你。
让我们假设所有函数都为 float
和 double
重载做“正确的事”:
void f(float x) {/*do something*/};
void f(double x) {/*do the same thing*/};
此外,当只有一个重载可用时,我们可以使用任一类型的文字来调用它:
void f_float(float x) {/*do something*/};
void f_double(double x) {/*do the same thing*/};
f_float(3.0); // ok
f_float(3.0f); // ok
f_double(3.0); // ok
f_double(3.0f); // ok
float
s 转换为 double
s,反之亦然。
如果所有代码都可以使用 float
或 double
,那么故事就此结束。但是,您不需要做一些“有趣”的事情来破解代码。
I haven't found any satisfactory answer that shows an actually relevant situation, where the distinction is important.
当文字的类型用于推断其他事物的类型时,这种区别很重要。能够在 double
和 float
之间转换并不是您需要能够用 double
文字替换任何 float
文字而不破坏代码的全部。
在上面的示例中,f_float
可以用 3.0
或 3.0f
调用。现在假设您有一个只接受 std::vector<float>
:
void bar(const std::vector<float>& x){}
以及给定单个值的东西构造一个向量:
template <typename T>
std::vector<T> make_vect(const T& t){ return {T{}}; }
然后文字的类型使代码要么失败要么通过:
bar(make_vect(0.3f));
//bar(x.make_vect(0.3)); // ERROR
TL;DR
整点只是你可以在float
和double
之间转换,但一般来说some_template<float>
和some_template<double>
之间没有可用的转换。文字的类型可能是相关的,即使您不介意 float
和 double
之间的转换。将 3.0f
更改为 3.0
可以使代码中断,否则没问题