C++中prvalues的Cv资格14

AnT*_*AnT 12 c++ language-lawyer c++11 c++14

似乎C++ 11和C++ 14对prvalues的cv资格进行了不同的处理.

C++ 11坚持自C++ 98以来一直存在的"经典"方法:根据3.10/4 "非类prvalues总是有cv-unqualified类型".

C++ 14在3.10/4中包含类似的措辞,但是它作为注释呈现:"[注意:类和数组prvalues可以具有cv限定类型;其他prvalues总是具有cv非限定类型.请参阅第5章.结束说明]"

在第5条中,它说:

6如果prvalue最初具有类型"cv T",其中T是cv非限定的非类非数组类型,则在进行任何进一步分析之前将表达式的类型调整为T. 1

这个5/6条目是C++ 14中的新增内容.现在,它使用与参考类型结果一直使用的相同方法来处理prvalues的cv资格(参见5/5).

这种变化的原因是什么?C++ 11和之前拒绝非class prvalues拥有任何cv资格的权利.C++ 14表示非类非数组prvalues 可以具有cv资格,但在进一步分析之前,这些cv资格被丢弃.

我的猜测是,有一些新的(对于C++ 14)语言功能可以在某种情况下(在上述调整发生之前)以某种方式"看到"prvalues的cv资格.它们存在吗?如果是这样,这些功能是什么?2


问题源于以下上下文:想象一个编译器,它在内部实现this类的隐藏参数X作为类型的变量X *const.由于编译器需要this作为prvalue 公开,这const不应该导致C++ 11(或之前)中的任何问题,其中标量prvalues永远不会被cv限定.但是C++ 14呢?如果完全相同的编译器将其暴露this为类型的prvalue X *const,是否可能导致问题?


1在C++ 14中,5/6与3.10/4中的音符之间似乎存在矛盾,但音符无论如何都不是规范性的.我正在使用该文本的草稿版本.

2我最初的猜测是decltype.我甚至认为我尝试时找到了答案

std::cout << std::is_same<decltype((const int) 0), const int>::value << std::endl;
Run Code Online (Sandbox Code Playgroud)

在海湾合作委员会,其产出1.但是,看到Clang和VC++输出0(并且该规范decltype似乎不支持这种行为)我倾向于认为这只是GCC中的一个错误(从6.1开始)

TBB*_*Ble 4

根据github 上的提交,这样做是为了解决CWG1261: Explicit Handling of cv-qualification with non-class prvalues

this根据对该问题的评论,类型类别(正式为右值)似乎存在令人惊讶的变化空间,并且gcc 以前和 MSVC 目前使用const lvalue

该措辞将漏洞收紧,使其明确,例如,即使this通过某种编译器内部魔法,类型为 的纯右值X* const在进行任何进一步分析之前,它也会被调整为X*

同样,您给出的示例看起来确实像 gcc bug。decltype在应用 c 风格转换之前可能没有查看值类型。

它现在成为 [basic.lval]/4 中的注释的原因是,它现在是 [expr]/6 中新文本的结果,而不是在 [basic.lval]/4 中指定规则。

完全归功于TC在对该问题的评论中基本上回答了这个问题,包括对 gcc 错误修复的引用,以及先前对cv 限定的非类非数组纯右值的未指定行为的各种其他示例。