4

我正在阅读value categories,并遇到以下内容(为简洁起见,省略了很多):

以下表达式是纯右值表达式:

  • 文字(字符串文字除外),例如 42、true 或 nullptr;

特性:

  • 非类非数组纯右值不能是 cv 限定的。

但是......以下程序在 ideone.com和 g++ 5.4.0 上编译并运行良好:

#include <iostream>

int main() {
    std::cout << ((const int) 42) << std::endl;
}

我知道编译器提供了扩展,如果遇到未定义的行为,它们可以做各种各样的事情。我只是想弄清楚标准的要求。

N4296中,我发现以下相关段落:

[表达式]

[...内容省​​略...]

  1. 如果纯右值最初具有类型“cv T”,其中 T 是无 cv 限定的非类、非数组类型,则表达式的类型会在任何进一步分析之前调整为 T。

“最初”这个词让我很震惊。目前尚不清楚这是否允许作为另一个表达式的结果,例如用户将非类非数组纯右值显式转换为 cv 限定类型(产生另一个纯右值),或者这是否仅适用于“根" 表达式(42在这种情况下)。

我的问题是,标准是否允许这样的表达式(它只是去掉了 cv 限定符),还是不允许这样做(如果相关,这在哪里是强制性的)?

4

2 回答 2

2

您应该知道 cppreference 不是规范的。“不能”可能有两种解读方式:

  • 这是被禁止的,阿拉“不应该”

  • 它根本不可能发生,ala 不变量

您在文中列出的报价:

如果纯右值最初具有类型“cv T”,其中 T 是无 cv 限定的非类、非数组类型,则表达式的类型会在任何进一步分析之前调整为 T。

向我建议,一个 cv 限定的纯右值会降低限定,就像数组可以衰减为指针一样(澄清一下,这个规则不会发生在强制转换格式不正确的地方)。缺陷#1261确实使语言非常明确地说明了在哪里发生了什么。

于 2017-03-21T15:49:39.303 回答
2

感谢 SanderDeDycker 指出要搜索的标准的相关部分。

我的问题在N4296的以下部分得到了回答(重点是我的):

[expr.cast]

  1. 表达式 (T) cast-expression 的结果是 T 类型。如果 T 是左值引用类型或对函数类型的右值引用,则结果是左值;如果 T 是对对象类型的右值引用,则结果是 xvalue;否则结果是纯右值。[ 注意:如果 T 是非类类型,它是 cv 限定的,则在确定结果纯右值的类型时会丢弃 cv 限定符;见第 5 条。——尾注]

所以我们可以得出结论,诸如此类的表达式(const int) 42是完全合法的 C++。

于 2017-03-21T15:55:37.427 回答