gpt4 book ai didi

c++ - 为什么非常量引用不能绑定(bind)到临时对象?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:01:12 33 4
gpt4 key购买 nike

为什么不允许获取临时对象的非常量引用,getx() 返回哪个函数?显然,这是 C++ 标准禁止的但我感兴趣的是这种限制的目的,不是引用标准。

struct X
{
X& ref() { return *this; }
};

X getx() { return X();}

void g(X & x) {}

int f()
{
const X& x = getx(); // OK
X& x = getx(); // error
X& x = getx().ref(); // OK
g(getx()); //error
g(getx().ref()); //OK
return 0;
}
  1. 很明显,对象的生命周期不能成为原因,因为C++ 标准不禁止对对象的常量引用。
  2. 很明显,上面示例中的临时对象不是常量,因为允许调用非常量函数。例如,ref() 可以修改临时对象。
  3. 此外,ref() 允许您欺骗编译器并获得指向该临时对象的链接,这解决了我们的问题。

此外:

他们说“将一个临时对象分配给 const 引用可以延长该对象的生命周期”和“但是没有提到非 const 引用”。我的附加问题。以下赋值是否会延长临时对象的生命周期?

X& x = getx().ref(); // OK

最佳答案

从这里Visual C++ blog article about rvalue references :

... C++ doesn't want you to accidentallymodify temporaries, but directlycalling a non-const member function ona modifiable rvalue is explicit, soit's allowed ...

基本上,您不应该因为临时对象是临时对象并且随时都会消亡而尝试修改临时对象。您被允许调用非常量方法的原因是,好吧,只要您知道自己在做什么并且明确说明(例如,使用 reinterpret_cast),我们欢迎您做一些“愚蠢”的事情。但是,如果您将一个临时对象绑定(bind)到一个非常量引用,您可以“永远”传递它,只是为了让您对该对象的操作消失,因为在此过程中的某个地方您完全忘记了这是一个临时对象。

如果我是你,我会重新考虑我的函数设计。为什么 g() 接受引用,它是否修改参数?如果不是,请将其设为 const 引用,如果是,您为什么要尝试将临时传递给它,您不在乎您正在修改的是临时文件吗?为什么 getx() 仍然临时返回?如果您与我们分享您的真实场景和您想要完成的目标,您可能会得到一些关于如何实现的好建议。

违背语言和愚弄编译器很少能解决问题——通常它会产生问题。


编辑:解决评论中的问题:1) `X& x = getx().ref();//好吧 x 什么时候会死?` - 我不知道也不在乎,因为这正是我所说的“违背语言”的意思。该语言说“临时对象在语句末尾死亡,除非它们绑定(bind)到 const 引用,在这种情况下,当引用超出范围时它们就会死亡”。应用该规则,似乎 x 在下一条语句的开头已经死了,因为它没有绑定(bind)到 const 引用(编译器不知道 ref() 返回什么)。然而,这只是一个猜测。
  1. 我清楚地说明了目的:不允许修改临时对象,因为它没有意义(忽略 C++0x 右值引用)。问题“那为什么我可以调用非常量成员?”是一个很好的答案,但我没有比我上面已经说过的更好的答案了。

  2. 好吧,如果我关于 x in X& x = getx().ref(); 在语句末尾死亡的说法是正确的,那么问题就很明显了。

无论如何,根据您的问题和评论,我认为即使是这些额外的答案也不会令您满意。这是最后的尝试/总结:C++ 委员会决定修改临时对象没有意义,因此,他们不允许绑定(bind)到非常量引用。可能还涉及一些编译器实现或历史问题,我不知道。然后,出现了一些具体情况,决定排除万难,他们仍然允许通过调用非常量方法直接修改。但那是一个异常(exception)——你通常不允许修改临时文件。是的,C++ 通常就是那么奇怪。

关于c++ - 为什么非常量引用不能绑定(bind)到临时对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6529264/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com