【问题标题】:Constructing `long double` rvalue [duplicate]构造`long double`右值[重复]
【发布时间】:2018-08-27 21:30:45
【问题描述】:

假设我有以下 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&lt;long double&gt;(4)?这感觉很脏:我正在构造一个对象,而不是强制转换 int,即使编译器会忽略它。

【问题讨论】:

  • 4Lstatic_cast&lt;long double&gt;(4)
  • using long_double = long double; 并更改 fn_ld 签名以使用 typedef 将解决此问题。
  • 注意,double(4) 是一个显式类型转换,就像static_cast&lt;long double&gt;(4),所以它们在语义上是等价的。所以“我正在构造一个对象,而不是一个 int”并不是 100% 正确的。
  • @RichardCritten 4L 是长整数,你在想4.L
  • 我的解决方案就是使用L 后缀。实际的问题被证明是更普遍的,所以我投票结束我自己的问题作为重复。

标签: c++ syntax casting rvalue long-double


【解决方案1】:

type(value) 时,C++ 语法不允许类型名称中有空格。

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

return pow( 4.0L, 3.0L );

【讨论】:

    【解决方案2】:

    首先,原始代码不正确,默认接受它是一个 MSVC 错误,see this question 用于标准参考。


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

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

    你可以写powl(4, 3),有从整数到长双精度的隐式覆盖。

    在更一般的情况下,您的选项包括 (long double)4static_cast&lt;long double&gt;(4)4.L4.0LL 后缀加上 . 的存在意味着 long double 文字。


    这感觉很脏:我正在构造一个对象,而不是转换一个 int,即使编译器会忽略它。

    也许你对这方面有误解。代码double(4) 是一个演员;它的正式名称是显式类型转换(功能表示法)。强制转换是纯右值,除了一些在这里不相关的情况。

    从字面上看(哈哈)在导致类型为double 和值4 的纯右值的不同语法之间在语义上没有任何区别。

    对于类类型也是如此; (std::string)xstd::string(x)static_cast&lt;std::string&gt;(x) 在语义上都是相同的。

    【讨论】:

    • 我忘了在我的问题中询问它,但我很高兴您通过显式类型转换添加了关于幕后发生的事情的说明(但除此之外,这是最好的答案)。 ¶ 对于对象类型,我的语法会在语义上调用构造函数;我的印象是原始类型也是这样做的。
    • @imallett 原始类型没有构造函数。对于类类型,所有语法都调用构造函数
    • 关键是,我之前的心智模型可以通过假设原始类型具有隐式的编译器生成的构造函数来重现。
    猜你喜欢
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多