看起来C++11和C++14对于prvalues的cv限定符处理方式有所不同。
C++11坚持自C++98以来一直存在的“经典”方法:根据3.10/4,“非类prvalues始终具有cv未限定类型”。
C++14在3.10/4中包含类似的措辞,但是它被呈现为一个注释:“[注:类和数组prvalues可以具有cv限定类型;其他prvalues始终具有cv未限定类型。参见第5条。-end note]”
而在第5条中则说:
6 如果prvalue最初具有类型“cv T”,其中T是cv未限定的非类、非数组类型,则在进一步分析之前将表达式的类型调整为T。1
这个5/6的条目是C++14中新增的。它现在使用与引用类型结果一直使用的相同方法来处理prvalues的cv限定符(请参见5/5)。
这个改变的原因是什么?C++11及更早版本否认非类prvalues拥有任何cv限定符的权利。C++14表示,非类、非数组prvalues可以具有cv限定符,但是这些cv限定符在进一步分析之前会被丢弃。
我猜测可能有一些新的(对于C++14而言)语言特性,在正确的情况下可以“看到”prvalues的cv限定符(在上述调整发生之前)。它们存在吗?如果是这样,这些特性是什么?
问题源于以下背景:想象一个编译器,在内部将类X的隐藏参数this实现为类型为X *const的变量。由于编译器需要将this公开为prvalue,在C++11(或之前)中标量prvalues从不具有cv限定符,因此该常量不应导致任何问题。但是C++14呢?如果完全相同的编译器将此作为类型为X *const的prvalue公开,是否可能会导致问题?
1 5/6和C++14中3.10/4的注释似乎存在矛盾,但注释本身并不具有规范性。而且我正在使用文本的草案版本。
2 我最初的猜测是decltype。当我尝试时,我甚至认为找到了答案。
C++11坚持自C++98以来一直存在的“经典”方法:根据3.10/4,“非类prvalues始终具有cv未限定类型”。
C++14在3.10/4中包含类似的措辞,但是它被呈现为一个注释:“[注:类和数组prvalues可以具有cv限定类型;其他prvalues始终具有cv未限定类型。参见第5条。-end note]”
而在第5条中则说:
6 如果prvalue最初具有类型“cv T”,其中T是cv未限定的非类、非数组类型,则在进一步分析之前将表达式的类型调整为T。1
这个5/6的条目是C++14中新增的。它现在使用与引用类型结果一直使用的相同方法来处理prvalues的cv限定符(请参见5/5)。
这个改变的原因是什么?C++11及更早版本否认非类prvalues拥有任何cv限定符的权利。C++14表示,非类、非数组prvalues可以具有cv限定符,但是这些cv限定符在进一步分析之前会被丢弃。
我猜测可能有一些新的(对于C++14而言)语言特性,在正确的情况下可以“看到”prvalues的cv限定符(在上述调整发生之前)。它们存在吗?如果是这样,这些特性是什么?
问题源于以下背景:想象一个编译器,在内部将类X的隐藏参数this实现为类型为X *const的变量。由于编译器需要将this公开为prvalue,在C++11(或之前)中标量prvalues从不具有cv限定符,因此该常量不应导致任何问题。但是C++14呢?如果完全相同的编译器将此作为类型为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 开始)中的一个错误。
const int f()
,则f()
是prvalue,其类型根据[expr.call],“静态选择函数的返回类型”,将是const int
,因此需要某种措辞来消除const
。 - T.C.S*&& p = this;
这样的代码时存在问题。现在它们已经解决了这个问题。 - T.C.