为何主流编译器允许对std::stringstream<<返回的std::ostream&调用str()?
问题:为何这段std::stringstream代码现在能编译通过?
请看以下代码:
std::string s = (std::stringstream() << "foo").str();
按照C++旧标准的规则,这段代码本不应编译——因为std::stringstream::operator<<继承自std::ostream,返回的是std::ostream&,而std::ostream并没有str()成员函数。
但目前主流编译器均已接受该代码,过去它们却会拒绝编译。请问是什么标准变更导致了这一情况?
我对GCC、Clang和MSVC编译器进行了测试,确定了变更发生的版本:
| 编译器 | 拒绝至(版本) | 开始接受(版本) |
|---|---|---|
| GCC | 11.1 | 11.2 |
| Clang | 12.0.1 | 13.0.0 |
| MSVC | v19.14 | v19.15 |
这是C++20标准的一项调整导致的:
在C20之前,所有流插入运算符(operator<<)都继承自std::basic_ostream,统一返回basic_ostream&基类引用。但C20对std::basic_stringstream的流插入操作做了特殊处理,新增了针对它的重载,让operator<<返回basic_stringstream&派生类引用。这样一来,代码中(std::stringstream() << "foo")的结果类型就是std::stringstream&,自然可以直接调用str()成员函数。
你测试到的各编译器版本,正是它们完成C++20这一特性支持的版本,所以从对应版本开始,这段代码就能正常编译了。
内容的提问来源于stack exchange,提问作者Fareanor
相关产品推荐
相关产品推荐

