[英]Is this an instance of a reference-to-non-const binding to a temporary?
免责声明:此问题仅供理解。 我将在该字段中使用boost::lexical_cast
。 不过,它在现实世界中已经出现了。
请尝试以下 “内联” lex-cast方法:
#include <string>
#include <sstream>
#include <iostream>
int main()
{
const std::string s = static_cast<std::ostringstream&>(
std::ostringstream() << "hi" << 0
).str();
std::cout << s;
}
结果类似于0x804947c0
,因为与"hi"
一起使用的operator<<
是一个自由函数,其LHS必须采用std::ostream&
† ,并且临时std::ostringstream()
无法绑定到ref-to-非const
。 剩下的唯一匹配项是在RHS ††上取const void*
的operator<<
。
现在让我们交换操作数 :
#include <string>
#include <sstream>
#include <iostream>
int main()
{
const std::string s = static_cast<std::ostringstream&>(
std::ostringstream() << 0 << "hi"
).str();
std::cout << s;
}
结果为"0hi"
。
这在大多数情况下是有道理的,因为采用int
的operator<<
是基本ostream
†††的成员函数,因此可以在临时实例上调用。 该操作的结果是对ostream
基的引用,下一个operator<<
链接到该基,即读为(std::ostringstream() << 0) << "hi"
。
但是,那么为什么在该操作"hi"
下去,以产生预期的结果? LHS上的参考还不是临时的吗?
让我们专注于C ++ 03; 有人告诉我,第一个示例实际上可能是C ++ 11中的“预期”工作,这是由于rvalue的通用运算符。
† [C++03: 27.6.2.1]: template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&,charT*);
†† [C++03: 27.6.2.1]: basic_ostream<charT,traits>& operator<<(const void* p);
††† [C++03: 27.6.2.1]: basic_ostream<charT,traits>& operator<<(int n);
原因很简单。 如果您阅读了我问的问题:
您会注意到,获得“适当”引用而不是临时引用的技巧是在对象上调用一个方法(由于某种原因而不受限于非绑定限制),该方法将返回引用。
在上面的Nawaz回答中,他调用了std::ostream& std::ostream::flush()
,在您的情况下为:
std::ostringstream() << 0 << "hi"
您调用std::ostringstream& std::ostringstream::operator<<(int)
。
结果相同。
令人惊讶的行为是由于ostream
mishmash实现:一些operator<<
是成员方法,而另一些是自由函数。
您可以通过在对象上实现X& ref()
方法来对其进行测试:
struct X { X& ref(); };
void call(X& x);
int main() {
call(X{}); // error: cannot bind X& to a temporary
call(X{}.ref()); // OK
}
编辑 :但是为什么X&
( ref
的结果)不一样?
这是分类问题 。 临时是prvalue
而引用是lvalue
。 引用只允许绑定到lvalue
。
当然,由于方法可以在rvalue
上调用(因此可以在prvalue
上调用),并且那些方法可以返回对其调用对象的引用,因此我们可以轻松绕过傻(1), 只允许将引用绑定到lvalue
限制。 。
(1)这也与rvalue
可以绑定到const-reference的事实不一致。
LHS上的参考还不是临时的吗?
它是对临时(返回值)的左值引用,该临时值仍然是左值,因此可以绑定到左值引用。
从生命周期而非l / rvalueness角度考虑临时人员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.