免责声明:此问题仅供参考。我将在该字段中使用boost::lexical_cast
。 It has sort of come up in the real world in places, though. 子>
以{inline“lex-cast方法取the following attempt:
#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
,因为与operator<<
一起使用的"hi"
是一个自由函数,其LHS必须采用std::ostream&
† ,而临时std::ostringstream()
无法绑定到ref-to-non - const
。唯一剩下的匹配是operator<<
,它在RHS ††上取const void*
。
#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"
。
这很有意义,因为operator<<
int
是基础ostream
†††的成员函数,因此,很好在临时调用。该操作的结果是对ostream
基数的引用,下一个operator<<
被链接到该基数,即将其读作(std::ostringstream() << 0) << "hi"
。
但为什么呢 对"hi"
的操作会继续产生预期结果? LHS上的参考不是暂时的吗?
让我们关注C ++ 03;我被告知,由于rvalues的catch-all运算符,第一个例子实际上可能在C ++ 11中作为“预期”工作。
† [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);
答案 0 :(得分:3)
原因很简单。如果你读到我问过的问题:
std::ostringstream printing the address of the c-string instead of its content.
你会注意到获得“正确”引用而不是临时引用的技巧是调用对象上的方法(不限于由于某种原因的非约束限制),这将返回引用。
在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
的结果)处理相同的内容?
这是classification的问题。临时是prvalue
,而引用是lvalue
。引用仅允许绑定到lvalue
。
当然,因为可以在rvalue
上调用方法(因而prvalue
),并且这些方法可能会返回对它们被调用的对象的引用,我们可以轻松绕过愚蠢的(1)只允许引用绑定到lvalue
限制...
(1)它也与rvalue
可以绑定到const-reference的事实不一致。
答案 1 :(得分:2)
LHS的参考资料是否仍然是暂时的?
它是对临时值(返回值)的左值引用,它仍然是左值,因此可以绑定到左值引用。
从终身而不是l / rvalueness的角度考虑临时性。