为什么编译器现在接受在从 std::stringstream::operator<<() 返回的 std::ostream& 上调用 str() 成员?

Far*_*nor 42 c++ language-lawyer

考虑以下行:

std::string s = (std::stringstream() << "foo").str();
Run Code Online (Sandbox Code Playgroud)

这不应该编译,因为std::stringstream::operator<<()它被继承std::ostream并返回一个没有成员的std::ostream&对象。str()

看来主要的编译器现在接受了这些代码,而他们过去并不接受。发生了什么标准变化来使这个编译?

我用GCCClangMSVC做了一些测试,我可以找到发生更改的版本:

编译器 拒绝直到(版本) 接受来自(版本)
海湾合作委员会 11.1 11.2
12.0.1 13.0.0
MSVC v19.14 v19.15

您可以在这里找到测试

mol*_*ilo 45

他们几乎同时添加了右值重载(请参阅此处)。

右值重载是C++11 中引入的,它返回与其左侧操作数相同类型的流。

正如评论中所指出的,它似乎在整整十年后才被添加到编译器中的原因是,它是最近才被追溯添加到 C++11 中的,可能是在被批准包含在 C++20 中之后。

我将把它变成一个社区维基,以防有人有兴趣和耐心去寻找追溯添加背后的原因并修改答案。