似乎C ++ 11和C ++ 14对prvalues的cv资格进行了不同的处理。
C ++ 11坚持自C ++ 98以来一直存在的“经典”方法:根据3.10 / 4 “非类prvalues总是有cv-unqualified类型”。 / p>
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
公开为X *const
类型的prvalue,是否可能导致问题?
1 在5/6与C ++ 14中的3.10 / 4中的注释之间似乎存在矛盾,但是注意事项无论如何都不是规范性的。我正在使用该文本的草稿版本。
2 我最初的猜测是decltype
。我甚至认为,当我尝试
std::cout << std::is_same<decltype((const int) 0), const int>::value << std::endl;
GCC中的,输出1
。但是,看到Clang和VC ++输出0
(以及decltype
的规范似乎不支持这种行为)我倾向于认为这只是GCC中的一个错误(从6.1开始) )
答案 0 :(得分:1)
根据commit on github,这样做是为了解决CWG1261: Explicit handling of cv-qualification with non-class prvalues
根据对该问题的评论,似乎this
(正式为 prvalue )的类型类别存在令人惊讶的变化空间,而gcc formerly和MSVC目前正在使用a const lvalue 。
措辞收紧洞是明确的,例如,即使this
是某个编译器内部魔法,也是X* const
,的prvalue,在进行任何进一步的分析之前它被调整为X*
。
同样,您给出的示例看起来像gcc错误。可能decltype
在应用c样式转换之前没有查看值类型。
它现在是[basic.lval] / 4中的一个注释的原因是它现在是[expr] / 6中新文本的结果,而不是在[basic.lval] / 4中指定规则。
完全赞同T.C.已在问题评论中基本回答了此问题,包括对gcc bug-fix的引用,以及 cv-qualified之前未充分指定的行为的各种其他示例非类非数组prvalues 。