c++ constexpr vs const vs constexpr const [复制]

bxfogqkk  于 9个月前  发布在  其他
关注(0)|答案(3)|浏览(110)

此问题在此处已有答案

What's the difference between constexpr and const?(10个答案)
Initializing a constexpr with a const, -- int vs float(2个答案)
3天前关闭。
const-vs-constexpr-on-variables
这家伙说的关于constexpr的是正确的if double被使用(或者当然是float)。然而,如果你把var类型从double改为整数类型,比如int,char,等等,一切都正常。为什么会发生这种情况?
http://ideone.com/DAWABE

int main() 
{
    const int PI1 = 3;
    constexpr int PI2 = 3;
    constexpr int PI3 = PI1;  // works
    static_assert(PI1 == 3, "");  // works

    const double PI1__ = 3.0;
    constexpr double PI2__ = 3.0;
    constexpr double PI3__ = PI1__;  // error
    static_assert(PI1__ == 3.0, "");  // error
    return 0;
}

字符串
Update:下面这行是个错误,我的意思是PI3__ = PI1__

constexpr double PI3__ = PI1;  // I meant PI1__


问题:
1.为什么const int = 3是编译时间常数,而const double = 3.0不是?
1.有什么理由让我使用constexpr const int val;而不是constexpr int val吗?它们似乎做的完全一样。

k7fdbhmy

k7fdbhmy1#

从注解中看,OP似乎要求标准引用,将const int定义为编译时常数,但const double不是。
相应的细节见5.19,Constant Expressions。特别是:
.一个左值到右值的转换(4.1),除非它被应用到一个整数或枚举类型的非易失性glvalue,该类型引用一个非易失性const对象,该对象具有一个先前的初始化,用一个常量表达式初始化.
int是整数类型,而double不是。

cedebl8k

cedebl8k2#

基于你在评论中的回答,这是我的答案。C++标准很清楚。GCC 5.1在这里工作得很好:https://godbolt.org/g/2oV6Hk
类型T的转换常量表达式是隐式转换为类型T的表达式,其中转换表达式是常量表达式,隐式转换序列仅包含§ 5.20 134 c ISO/IEC N4567
[...]

(4.6)-积分促销(4.5),
(4.7)-除收缩转换(8.5.4)之外的整数转换(4.7)

[...]
有关n4567中收缩转换(8.5.4/7)的参考:
收缩转换是隐式转换

  • 从浮点类型到整数类型,或者
  • 从long double到double或float,或者从double到float,除非源是常量表达式,并且转换后的实际值在可以表示的值范围内(即使无法精确表示),或者
  • 从整数类型或无作用域枚举类型转换为浮点类型,除非源是常量表达式,并且转换后的实际值将适合目标类型,并且在转换回原始类型时将生成原始值,或者
  • 从整数类型或无作用域枚举类型转换为不能表示原始类型的所有值的整数类型,除非源是常量表达式,并且转换后的实际值将适合目标类型,并且在转换回原始类型时将生成原始值。
ecbunoof

ecbunoof3#

编译器不允许在constexpr变量初始化期间进行隐式收缩或非整数提升。
这将工作:

int main()
{
    const int PI1 = 3;
    constexpr int PI2 = 3;
    constexpr int PI3 = PI1;  // works
    static_assert(PI1 == 3, "");  // works

    const double PI1__ = 3;
    constexpr double PI2__ = 3;
    constexpr double PI3__ = double(PI1);  // works with explicit cast
    static_assert(PI2__ == 3, "");  // works now. PI1__ isn't constexpr
    return 0;
}

字符串

相关问题