prvalues的cv资格(重访)

AnT*_*AnT 19 c++ language-lawyer temporary-objects c++17 prvalue

这是我之前的问题的后续问题,其中明显的共识是,prvalues的cv资格处理的变化只是一个相当小的和无关紧要的变化,旨在解决一些不一致性(例如返回prvalues并通过cv-qualified返回声明的函数)类型).

但是,我看到标准中的另一个地方似乎依赖于具有cv限定类型的constprvalues:通过临时实现转换初始化带有prvalues 的引用.有关措辞可在9.3.3/5中的多个地点找到

[...]如果转换的初始化程序是prvalue,则将其类型T4调整为键入"cv1 T4"([conv.qual])并应用临时实现转换([conv.rval])[...]

[...]否则,初始化表达式被隐式转换为"cv1 T1"类型的prvalue.应用临时实现转换,并将引用绑定到结果.

目的很明显是当我们进行实际的临时物化转换时

7.3.4临时实现转换
1类型T的prvalue可以转换为类型T的xvalue.此转换通过使用临时对象评估prvalue,从prvalue初始化类型为T的临时对象([class.temporary])它的结果对象,并生成一个表示临时对象的xvalue.[...]

T它作为输入接收的类型包括所需的cv资格.

但是在非类非数组prvalue的情况下,该cv资格如何在7.2.2/2中存活?

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

或者是吗?

例如,我们在这个例子中得到了什么样的临时性

const int &r = 42;
Run Code Online (Sandbox Code Playgroud)

暂时const与否?我们能做到吗

const_cast<int &>(r) = 101; // Undefined or not?
Run Code Online (Sandbox Code Playgroud)

没有触发未定义的行为?如果我没有弄错的话,最初的意图是const int在这种情况下获得临时性.它仍然是真的吗?(对于班级类型,答案很清楚 - 我们得到一个const临时的.)

use*_*445 1

为什么怀疑7.2.2的语言?这似乎非常明确,cv 限定符在非类、非数组纯右值上被丢弃,因此临时物化中的类型 T 是非常量、非易失性类型。

如果不是这种情况,那么您将无法将纯右值绑定到非常量右值引用。然而,该标准似乎极有可能旨在接受如下程序:

#include <type_traits>

template<typename T> void
f(T &&t)
{
  static_assert(std::is_same_v<decltype(t), int&&>);
  ++t;
}

int
main()
{
  f(5);
}
Run Code Online (Sandbox Code Playgroud)