C ++ 14中prvalue的Cv限定 [英] Cv-qualifications of prvalues in C++14

查看:114
本文介绍了C ++ 14中prvalue的Cv限定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 11和C ++ 14似乎对prvalue的cv限定有不同的对待.

C ++ 11遵循自C ++ 98以来一直存在的经典"方法:根据3.10/4 非类prvalue始终具有cv不合格的类型" . /p>

C ++ 14在3.10/4中包含类似的措词,但作为注释显示:"[[注意:类和数组prvalue可以具有cv限定的类型;其他prvalue始终具有cv不限定的类型.请参见第5章.–尾注]"

在第5条中说:

6 如果一个prvalue最初的类型为"cv T",其中T是cv不合格的非类,非数组类型,则将表达式的类型调整为T之前的T任何进一步的分析. 1

此5/6条目是C ++ 14中的新增功能.现在,它使用引用类型结果始终使用的相同方法来处理prvalue的cv限定词(请参阅5/5).

此更改的原因可能是什么? C ++ 11及之前拒绝非类prvalues拥有任何cv资格的权利. C ++ 14表示,非类,非数组prvalues 可以具有cv限定,但是在进行任何进一步分析之前,这些cv限定将被丢弃.

>

我的猜测是(对于C ++ 14)有些新的语言功能可以在适当的情况下(在进行上述调整之前)以某种方式查看" prvalue的cv限定词.它们存在吗?如果是的话,这些功能是什么? 2


问题源自以下上下文:想象一个编译器内部将类X的隐藏参数this实现为类型X *const的变量.由于要求编译器将this公开为prvalue,因此该const不应在C ++ 11(或更早版本)中导致任何问题,在C ++ 11中,标量prvalue永远都不是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开始)

解决方案

根据提交github ,这样做是为了解决 CWG1261:明确非类prvalue的简历资格处理

基于对该问题的评论,看来this(以前是 prvalue )的类型类别还有令人吃惊的变化余地,而 TC 的完全归功,因为他已在对问题的评论中基本回答了此问题,包括对gcc错误的引用-fix,以及以前未为 cv限定的非类非数组prvalues 指定行为的各种其他示例.

It appears that C++11 and C++14 treat cv-qualifications of prvalues differently.

C++11 sticks to the "classic" approach that has been around since C++98: according to 3.10/4 "non-class prvalues always have cv-unqualified types".

C++14 contains a similar wording in 3.10/4, but it is presented as a note: "[Note: class and array prvalues can have cv-qualified types; other prvalues always have cv-unqualified types. See Clause 5. —end note ]"

And in Clause 5 it says:

6 If a prvalue initially has the type "cv T," where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.1

This 5/6 entry is new in C++14. It now treats cv-qualifications of prvalues using the same approach that has always been used with results of reference type (see 5/5).

What could be the reason for this change? C++11 and before denied non-class prvalues the right to have any cv-qualifications. C++14 says that non-class, non-array prvalues can have cv-qualifications, but these cv-qualifications are discarded prior to any further analysis.

My guess would be that there are some new (for C++14) language features that can somehow "see" cv-qualifications of prvalues under the right circumstances (before the aforementioned adjustment takes place). Do they exist? And if so, what are these features?2


The question originated from following context: imagine a compiler that internally implements hidden parameter this of class X as a variable of type X *const. Since the compiler is required to expose this as a prvalue, that const should not lead to any problems in C++11 (or before), where scalar prvalues are never cv-qualified. But what about C++14? If the very same compiler exposes that this as a prvalue of type X *const, could it possibly lead to problems?


1 There appears to be a contradiction between 5/6 and the note in 3.10/4 in C++14, but notes are not normative anyway. And I'm using a draft version of the text.

2 My initial guess was decltype. And I even thought that I found the answer when I tried

std::cout << std::is_same<decltype((const int) 0), const int>::value << std::endl;

in GCC, which outputs 1. However, seeing that Clang and VC++ output 0 (and that the spec of decltype does not seem to support this behavior) I'm inclined to believe that this is just a bug in GCC (starting from 6.1)

解决方案

According to the commit on github, this was done to resolve CWG1261: Explicit handling of cv-qualification with non-class prvalues

Based on comments to the question it seems there was room for surprising variations in type category of this (formally a prvalue) and that gcc formerly and MSVC currently instead used a const lvalue.

The wording tightens up the hole to be explicit that, e.g., even if this is by some compiler-internal magic a prvalue of type X* const, prior to any further analysis it is adjusted to X*.

Similarly, your given example does look like a gcc bug. Possibly decltype isn't looking at the value type before applying the c-style cast.

The reason it's now a note in [basic.lval]/4 is that it's now a consequence of the new text in [expr]/6, rather than specifying the rule in [basic.lval]/4.

Full credit to T.C. for having basically answered this in the comments on the question, including the reference to the gcc bug-fix, and various other examples of previously under-specified behaviours for cv-qualified non-class non-array prvalues.

这篇关于C ++ 14中prvalue的Cv限定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆