构建“long double”右值

Constructing `long double` rvalue

假设我有以下 C++ 代码:

#include <cmath>
long double fn_d() {
    return pow( double(4), double(3) );
}
long double fn_ld() {
    return powl( long double(4), long double(3) );
}

MSVC 对此很满意,但 GCC 和 Clang 都对第二个函数感到困惑,写作(GCC 的输出):

<source>:6:34: error: expected primary-expression before 'long'
6 |     return powl( long double(4), long double(3) );
  |                                  ^~~~

请注意上面的 fn_d(...),效果很好。 假设这不是两个编译器中的错误,我应该怎么做?


注意:(long double)(4)(即演员)不行。它跳闸 -Wold-style-cast(你应该使用)。也许 static_cast<long double>(4)?这感觉很脏:我正在构造一个对象,而不是转换 int,即使编译器会忽略它。

C++ 语法不允许您在执行 type(value) 时在类型名称中包含 space。

相反,您可以使用适当的后缀而不是尝试使用 type(value)。对于 long double 你可以使用 l/L 比如

return pow( 4.0L, 3.0L );

首先,原代码不正确,是MSVC的bug,默默接受,see this question标准参考


由于powl是签名的非重载函数:

long double powl(long double x, long double y);

你可以只写powl(4, 3),从integer到long double的隐式转换

在更一般的情况下,您的选项包括 (long double)4static_cast<long double>(4)4.L4.0LL 后缀与文字中 . 的存在相结合意味着 long double 文字。


This feels dirty: I'm constructing an object, not casting an int, even if the compiler will elide it.

可能你对这方面有误解。代码 double(4) 是强制转换;它的正式名称是显式类型转换(函数符号)。转型是 prvalues,除了一些与这里无关的情况。

导致类型 double 和值 4.

的纯右值的不同语法在语义上没有任何区别(哈哈)

class 类型也是如此; (std::string)xstd::string(x)static_cast<std::string>(x) 在语义上完全相同。