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)