为什么在这里创建临时对象


class X{
public:
X(){}
};
class Y{
public:
Y(X x) { std::cout << "Temporary created!"; }
};
int main(){
X x;
const Y& y = x;
return 0;
}

为什么在这里创建临时对象(类型为Y(?在这种情况下,我理解临时对象的必要性,但我不明白标准对此有何规定。如果我们看一下标准,如果我没有错的话,唯一适合我们的情况就是绑定对prvalue的引用。那么,const Y& y = x中的子表达式x是否被转换为prvalue,或者这里发生了其他事情?

我还研究了lvalue->右价转换,但整个事情似乎解释得很糟糕。它没有说明会发生这种类型转换的场景。据我所知,这种转变发生的次数比我想象的要多。例如,如果我们看一下cpp.reference上的隐式转换,几乎每一节都以"开头;XXX类型的prvalue可以转换为YYY"这表明在隐式转换中,大多数时候我们使用左值->作为某种基转换的右值转换。与此密切相关的是,我也研究了这个话题,它可能是对整个情况的一个很好的理解,但也可能相当过时。

所以基本上,我有两个问题。标题中的第一个和(可能不相关(第二个:什么时候左值->真的发生了右值转换吗?

编辑:关于我的第一个问题(来自标题(,我提出了一个理论,我认为它符合草案。基本上,表达式x被转换为const Y类型的prvalue,但不创建任何对象。之后,我们有一个到prvalue的绑定,它会导致将prvalue转换为xvalue的临时物化。只有这样,我们才能将const引用绑定到该临时对象。我离真相还有多远?

我相信x正被隐式转换为Y对象。

隐式转换

对于一些发明的临时t,表达式e被称为隐式可转换为T2,当且仅当T2可以从e复制初始化,即声明T2 t = e;是良好形式的(可以编译(。

Y可以从X复制初始化,调用Y(X x) { ... }构造函数。


r值可以绑定到常量l值引用。因此,const Y& y = x;是有效的。

为什么要在这里创建临时对象?

您提供的构造函数Y::Y(X x)称为转换构造函数。通过提供这个构造函数,基本上就是说X类型的对象可以用于预期Y类型的对象的地方。

现在,让我们看看你的案子发生了什么。当你写道:

const Y& y = x;

在上面的语句中,y是常量Y左值引用。这意味着y期望绑定到Y类型的对象。但是您提供了类型为X的对象x。因此,将存在xYprvalue隐式转换,这将使用转换构造函数来完成。这就是为什么它首先被称为转换构造函数。

但请注意,const Y&期望有一个glvalue,而我们目前在右侧有一个prvalue时物化规则生效,prvalue表达式转换为xvalue。现在,由于允许对常量Y左值引用绑定到xvalue(因为xvalue也是glvalue(,y成功绑定到该物化的xvalue。

最新更新