const-vs-constexpr-on-variables
关于constexpr的人说的是正确的if double
(当然还是float
)。但是,如果将var类型从double
更改为整数类型(如int,char等),则一切正常。为什么会这样?
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__
问题:
为什么const int = 3
是编译时常量而const double = 3.0
不是?
我有理由将constexpr const int val;
用于constexpr int val
吗?他们似乎都完全一样。
答案 0 :(得分:2)
根据您在评论中的回答,这是我的答案。 C ++标准非常清楚。 GCC 5.1在这里工作得很好:https://godbolt.org/g/2oV6Hk
T类型的转换常量表达式是一个表达式,隐式转换为类型T,其中转换后的表达式 expression是一个常量表达式,隐式转换序列只包含 §5.20134 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,除非source是常量表达式,转换后的实际值在可以表示的值范围内(即使它不能精确表示) ,或
- 从整数类型或无范围枚举类型到浮点类型,除非源是常量表达式,转换后的实际值将适合目标类型,并在转换回原始值时生成原始值类型,或
- 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除非source是常量表达式,并且转换后的实际值将适合目标类型并将生成转换回原始类型时的原始值。
答案 1 :(得分:1)
从评论看来,OP似乎要求标准引用将const int
定义为编译时常量,但const double
不是。
相应的详细信息可在5.19 Constant Expressions
中找到。特别是:
......左值到右值的转换(4.1),除非它适用于a 整数或枚举类型的非易失性glvalue,指的是a 具有前面初始化的非易失性const对象,已初始化 一直表达......
int
是一个整数类型,而double
则不是。
答案 2 :(得分:0)
编译器在初始化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;
}