【问题标题】:Clarification of converted constant expression definition转换常量表达式定义的说明
【发布时间】:2015-12-01 10:26:28
【问题描述】:

(在my recent questionanother question 之后。)

[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();

现在,如果我写

bar<foo()>();

那么哪个表达式应该是常量表达式?整个 foo() 表达式应该保持不变,还是像 static_cast&lt;int&gt;(foo()) 这样的表达式?

根据我对my recent question 的了解,只有后者需要保持不变。这是真的吗?

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

【问题讨论】:

    标签: c++ language-lawyer


    【解决方案1】:

    首先,哪个表达式执行“转换后的表达式”(强调) 参考?

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

    T e = /* original expression */;
    

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

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

    e.

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

    二、“引用绑定”指的是整个流程的哪个阶段 去?

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

    【讨论】:

    • 但是如果both表达式必须是constexpr,那为什么here只有后一个调用失败呢? ax 都没有 const,但 aconstexpr 转换。
    • @Petr 这是一个完全不同的例子。
    • 但是这种差异的本质是什么?在所有情况下,原始表达式都不是常量,是吗?
    • @Petr 原始表达式a 是常量。 x 不是。我已经调整了答案,但是确实不清楚,谢谢。
    • @Petr Simple: x itself 是一个常量表达式,但转换后的表达式在隐式转换期间执行了左值到右值的转换。但是,根据 [expr.const]/(2.7.1),x 上的这种 l-t-r 转换在常量表达式中是不允许的,因为 x 不是 const。
    猜你喜欢
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多