【问题标题】:no member named 'str' in 'std::basic_ostream<char>' with gcc and clang, but no problem with msvc使用 gcc 和 clang 在 'std::basic_ostream<char>' 中没有名为 'str' 的成员,但使用 msvc 没有问题
【发布时间】:2020-04-15 19:19:25
【问题描述】:

此代码 sn-p (https://gcc.godbolt.org/z/hKDMxm):

#include <iostream>
#include <sstream>

using namespace std;

int main() {
    auto s = (ostringstream{} << "string").str();
    cout << s;
    return 0; 
}

使用 msvc 按预期编译和运行,但使用 clang 9.0.0 和 gcc 9.2 编译失败,并给出以下错误消息:no member named 'str' in 'std::basic_ostream&lt;char&gt;'。看看https://en.cppreference.com/w/cpp/io/basic_ostringstream/str,显然str()ostringstream 的成员。为什么 clang 和 gcc 无法编译这段代码?

【问题讨论】:

    标签: c++ gcc clang std


    【解决方案1】:

    显然有str()ostringstream的成员

    是的,但是根据cppreference&lt;&lt; 的重载应该返回对basic_ostream&lt;...&gt; 的引用,而不是ostringstream

    libstdc++(GCC 的标准库)正是这样做的,而 libc++(Clang 的标准库)和 MSVC 的标准库在技术上表现不正确。

    但是,似乎有一个开放的defect report 表明与右值流一起使用的&lt;&lt; 的重载应该返回传递给它的确切流类型。如果它被接受,您的代码将是有效的。

    【讨论】:

    • 这个答案是正确的,但如果能提出解决问题的方法就好了,在要调用.str()的代码中比#if ... #else ...更好。
    • @taranaki 解决方案是以经典方式使用stringstream:创建一个(命名的)变量。我不知道一个好的 oneliner 替代方案,但您可以创建一个可变参数函数(将参数与流连接起来),或使用 libfmt。
    【解决方案2】:

    operator&lt;&lt;std::ostream 的成员,并按照here 的描述返回std::ostream&amp;

    MSVC 显然对std::ostringstream 有自己的重载此运算符,标准中没有什么

    【讨论】:

    • 链接到文档时,请考虑链接到 cppreference.com 而不是 cplusplus.com,因为它存在与文档准确性相关的多个问题。
    • 这个答案需要进行一些清理(例如,这里发生的事情没有什么明显的)但这是正确的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 2014-09-26
    • 2015-11-14
    • 2013-11-16
    • 2015-01-10
    • 1970-01-01
    相关资源
    最近更新 更多