繁体   English   中英

这是对非const的引用绑定到临时实例的实例吗?

[英]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"

这在大多数情况下是有道理的,因为采用intoperator<<是基本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);

原因很简单。 如果您阅读了我问的问题:

std :: ostringstream打印c字符串的地址而不是其内容。

您会注意到,获得“适当”引用而不是临时引用的技巧是在对象上调用一个方法(由于某种原因而不受限于非绑定限制),该方法将返回引用。

在上面的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM