且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何得到非const引用不能绑定到临时对象?

更新时间:2021-11-10 06:12:59

从此关于右值引用的Visual C ++博客文章


... C ++不希望你不小心
修改临时值,而是直接
调用非成员函数
a可修改右值是显式的,所以
是允许的...

... C++ doesn't want you to accidentally modify temporaries, but directly calling a non-const member function on a modifiable rvalue is explicit, so it's allowed ...

基本上,你不应该尝试修改临时性,因为它们是临时对象,而且会立刻死亡。允许调用非const方法的原因是,只要你知道你在做什么,你是明确的(比如,使用reinterpret_cast),欢迎你做一些愚蠢的事情。但是如果你绑定一个临时的非const引用,你可以继续传递它永远只是为了你的对象的操作消失,因为在某个地方,你完全忘了这是一个暂时的。

Basically, you shouldn't try to modify temporaries for the very reason that they are temporary objects and will die any moment now. The reason you are allowed to call non-const methods is that, well, you are welcome to do some "stupid" things as long as you know what you are doing and you are explicit about it (like, using reinterpret_cast). But if you bind a temporary to a non-const reference, you can keep passing it around "forever" just to have your manipulation of the object disappear, because somewhere along the way you completely forgot this was a temporary.

如果我是你,我会重新思考我的功能的设计。为什么是g()接受引用,它修改参数吗?如果没有,使它const引用,如果是,为什么你尝试通过临时,它不是你的临时你正在修改吗?为什么getx()仍然返回临时?如果你与我们分享你的真实场景和你想要完成的事情,你可能会得到一些关于如何做到的好建议。

If I were you, I would rethink the design of my functions. Why is g() accepting reference, does it modify the parameter? If no, make it const reference, if yes, why do you try to pass temporary to it, don't you care it's a temporary you are modifying? Why is getx() returning temporary anyway? If you share with us your real scenario and what you are trying to accomplish, you may get some good suggestions on how to do it.

违背语言和欺骗编译器很少解决问题 - 通常会产生问题。

Going against the language and fooling the compiler rarely solves problems - usually it creates problems.



编辑:在注释中解决问题:
1) X& x = getx()。ref(); // OK when will x die? - 我不知道,我不在乎,因为这正是我的意思是违背语言。语言说临时在语句的末尾死去,除非它们被绑定到const引用,在这种情况下,当引用超出范围时,它们死亡。应用该规则,似乎x已经在下一条语句的开始处已经死了,因为它没有绑定到const引用(编译器不知道ref()返回什么)。这只是一个猜测。


Addressing questions in comment: 1) X& x = getx().ref(); // OK when will x die? - I don't know and I don't care, because this is exactly what I mean by "going against the language". The language says "temporaries die at the end of the statement, unless they are bound to const reference, in which case they die when the reference goes out of scope". Applying that rule, it seems x is already dead at the beginning of the next statement, since it's not bound to const reference (the compiler doesn't know what ref() returns). This is just a guess however.

2)我清楚地说明了目的:不允许修改临时表,因为它没有意义(忽略C ++ 0x右值引用)。问题为什么我允许调用非常量成员?是一个好的,但我没有比我已经说明的更好的答案。

2) I stated the purpose clearly: you are not allowed to modify temporaries, because it just does not make sense (ignoring C++0x rvalue references). The question "then why am I allowed to call non-const members?" is a good one, but I don't have better answer than the one I already stated above.

3)好吧,如果我在 X& x = getx()。ref(); 在语句结束时,问题很明显。

3) Well, if I'm right about x in X& x = getx().ref(); dying at the end of the statement, the problems are obvious.

无论如何,根据你的问题和意见,我不认为即使这些额外的答案会满足你。这里是最后的尝试/总结:C ++委员会决定修改临时表没有意义,因此,它们不允许绑定到非const引用。可能是一些编译器实现或历史问题也涉及,我不知道。然后,一些特定的情况出现,并且决定,对于所有的可能性,他们仍然允许通过调用非const方法的直接修改。但这是一个例外 - 你通常不允许修改临时。是的,C ++常常是奇​​怪的。

Anyway, based on your question and comments I don't think even these extra answers will satisfy you. Here is a final attempt/summary: The C++ committee decided it doesn't make sense to modify temporaries, therefore, they disallowed binding to non-const references. May be some compiler implementation or historic issues were also involved, I don't know. Then, some specific case emerged, and it was decided that against all odds, they will still allow direct modification through calling non-const method. But that's an exception - you are generally not allowed to modify temporaries. Yes, C++ is often that weird.