为什么不允许获取对临时对象的非常量引用,
哪个函数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;
}
- 很明显,对象的生命周期不可能是原因,因为
对对象的常量引用是不禁止按照 C++ 标准。
- 很明显,上面示例中的临时对象不是常量,因为允许调用非常量函数。例如,
ref()
可以修改临时对象。
- 此外,
ref()
允许你愚弄编译器并获得到这个临时对象的链接,这解决了我们的问题。
此外:
他们说“将临时对象分配给 const 引用可以延长该对象的生命周期”和“但没有提及非 const 引用”。
我的附加问题。以下赋值是否会延长临时对象的生命周期?
X& x = getx().ref(); // OK
由此有关右值引用的 Visual C++ 博客文章 https://devblogs.microsoft.com/cppblog/rvalue-references-c0x-features-in-vc10-part-2/:
... C++ 不希望你意外
修改临时的,但直接
调用非常量成员函数
可修改的右值是显式的,所以
这是允许的...
基本上,您不应该尝试修改临时对象,因为它们是临时对象,并且随时都会消失。允许您调用非常量方法的原因是,只要您知道自己在做什么并且明确地了解它(例如使用reinterpret_cast),我们就欢迎您做一些“愚蠢”的事情。但是,如果您将临时引用绑定到非常量引用,则可以“永远”继续传递它,只是为了让您对对象的操作消失,因为在此过程中您完全忘记了这是一个临时引用。
如果我是你,我会重新考虑我的功能的设计。为什么 g() 接受引用,它会修改参数吗?如果不是,请将其设为 const 引用,如果是,为什么要尝试将临时值传递给它,你不关心它是你正在修改的临时值吗?为什么 getx() 返回临时值?如果您与我们分享您的真实场景以及您想要实现的目标,您可能会得到一些关于如何实现的好建议。
违背语言并欺骗编译器很少能解决问题——通常它会产生问题。
Edit: Addressing questions in comment:
-
X& x = getx().ref(); // OK when will x die?
- 我不知道,也不关心,因为这正是我所说的“违背语言”的意思。该语言说“临时对象在语句末尾死亡,除非它们绑定到 const 引用,在这种情况下,当引用超出范围时它们就会死亡”。应用该规则,看起来 x 在下一个语句的开头就已经死了,因为它没有绑定到 const 引用(编译器不知道 ref() 返回什么)。然而,这只是一个猜测。
-
我清楚地说明了目的:不允许修改临时变量,因为它没有意义(忽略 C++0x 右值引用)。问题是“那为什么我可以称呼非常数成员呢?”是一个很好的答案,但我没有比上面已经说过的更好的答案。
-
好吧,如果我对 x 的看法是正确的X& x = getx().ref();
声明最后就死了,问题就很明显了。
无论如何,根据您的问题和评论,我认为即使这些额外的答案也不会令您满意。这是最后的尝试/总结:C++ 委员会认为修改临时变量没有意义,因此,他们不允许绑定到非常量引用。我不知道,可能还涉及一些编译器实现或历史问题。然后,出现了一些具体情况,尽管困难重重,他们仍然允许通过调用非常量方法进行直接修改。但这是一个例外 - 通常不允许您修改临时变量。是的,C++ 常常就是那么奇怪。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)