gpt4 book ai didi

c++ - 这是一个引用到非常量绑定(bind)到临时的实例吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:30:27 27 4
gpt4 key购买 nike

免责声明:这个问题是为了理解。我将使用 boost::lexical_cast在该领域。 It has sort of come up in the real world in places, though.


the following attempt在“内联”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 ,因为 operator<<适用于 "hi"是一个自由函数,它的 LHS 必须取 std::ostream& ,临时std::ostringstream()无法绑定(bind)到非 const 的引用.唯一剩下的比赛是 operator<<这需要 const void*在 RHS†† 上。

现在let's swap the operands :

#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是 base ostream 的成员函数††† 因此可以在临时对象上调用。该操作的结果是对 ostream 的引用基地,下一个operator<<被链接起来,即读作 (std::ostringstream() << 0) << "hi" .

但是为什么那个操作在"hi"上呢?继续产生预期的结果? LHS 上的引用不还是临时的吗?


让我们关注 C++03;有人告诉我,由于右值的包罗万象的运算符,第一个示例实际上可能在 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);

最佳答案

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

std::ostringstream printing the address of the c-string instead of its content.

您会注意到获得“正确”引用而不是临时引用的诀窍是调用对象上的方法(由于某种原因不限于非绑定(bind)限制),该方法将返回引用。

在上面 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 .引用只允许绑定(bind)到 lvalue .

当然,因为可以在 rvalue 上调用方法(因此 prvalue )并且这些方法可能会返回对调用它们的对象的引用,我们可以轻松绕过愚蠢的 (1) 引用只允许绑定(bind)到 lvalue 限制...

(1) 这也不符合 rvalue 的事实可以绑定(bind)到常量引用。

关于c++ - 这是一个引用到非常量绑定(bind)到临时的实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14393934/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com