转换后的常量表达式定义的澄清

Pet*_*etr 4 c++ language-lawyer

(继我最近的问题另一个问题之后。)

[expr.const]/4 表示:

T 类型的转换常量表达式是隐式转换为 T 类型的表达式,其中转换后的表达式是常量表达式,并且隐式转换序列仅包含

  • ...(清单略)

以及引用绑定(如果有)直接绑定的位置。

(强调我的。)

这里有两点我不太明白。

首先,“转换后的表达式”(强调)指的是哪个表达式?

例如考虑

class A; // assume it can be implicitly converted to `int`
A foo(); // or maybe constexpr
template<int n> void bar();
Run Code Online (Sandbox Code Playgroud)

现在,如果我写

bar<foo()>();
Run Code Online (Sandbox Code Playgroud)

那么哪个表达式应该是常量表达式呢?整个foo()表达式应该是恒定的,还是只是类似的东西static_cast<int>(foo())

据我从最近的问题中了解到,只有后者需要保持不变。这是真的?

第二,“引用绑定”指的是整个过程的哪个阶段?它是否仅指模板参数本身是引用(template<int& x>...)的情况?或者是否要求在类型转换或转换表达式求值期间发生的任何引用绑定都应该是直接的?或者它是否指的是尚未转换的表达式本身就是引用的情况(A& a=...; bar<a>();)?

Col*_*mbo 5

首先,“转换后的表达式”(强调)指的是哪个表达式?

隐式转换引入了相应初始化的临时变量:

T e = /* original expression */;
Run Code Online (Sandbox Code Playgroud)

e是“转换后的表达式”。T = int在你的情况下。

那么哪个表达式应该是常量表达式呢?

e

foo 此外,隐式调用的转换运算符函数必须是 constexpr 函数,按照[expr.const]/(2.2)

第二,“引用绑定”指的是整个过程的哪个阶段?

T是引用类型时,该引用(e在上面的示例中)应直接绑定。表达式内部或感兴趣之前不需要绑定。

  • @Petr Simple:“x”*本身*是一个常量表达式,但转换后的表达式在隐式转换期间执行了左值到右值的转换。然而,根据 [expr.const]/(2.7.1),在常量表达式中不允许对 `x` 进行这种 ltr 转换,因为 `x` 不是 const。 (2认同)