【问题标题】:Return stringstream from a function从函数返回字符串流
【发布时间】:2011-02-25 16:43:29
【问题描述】:

显然我在这里遗漏了一些关于字符串流的重要信息,但有人可以解释一下原因

#include <sstream>
using namespace std;

stringstream foo() {
  stringstream ss;
  return ss;
}

失败

In file included from /usr/include/c++/4.4/ios:39,
             from /usr/include/c++/4.4/ostream:40,
             from /usr/include/c++/4.4/iostream:40,
             from rwalk.cpp:1:/usr/include/c++/4.4/bits/ios_base.h: In copy constructor ‘std::basic_ios<char,    std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’:/usr/include/c++/4.4/bits/ios_base.h:790: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.4/iosfwd:47: error: within this context
/usr/include/c++/4.4/iosfwd: In copy constructor ‘std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)’:
/usr/include/c++/4.4/iosfwd:75: note: synthesized method ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’ first required here 
/usr/include/c++/4.4/streambuf: In copy constructor ‘std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::basic_stringbuf(const std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >&)’:
/usr/include/c++/4.4/streambuf:770: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]’ is private
/usr/include/c++/4.4/iosfwd:63: error: within this context
/usr/include/c++/4.4/iosfwd: In copy constructor ‘std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)’:
/usr/include/c++/4.4/iosfwd:75: note: synthesized method ‘std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::basic_stringbuf(const std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >&)’ first required here 
rwalk.cpp: In function ‘std::stringstream foo()’:
rwalk.cpp:12: note: synthesized method ‘std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)’ first required here 

如何正确地从函数返回字符串流? (编辑:添加了完整代码 sn-p 的标题并修复了错字)

【问题讨论】:

    标签: c++ stringstream


    【解决方案1】:

    在更正返回类型中的 type-o 后(Mahesh 指出),您的代码将无法在 C++03 中编译,因为 stringstream 不可复制。但是,如果您的编译器支持 C++0x,打开它可以让您的代码编译,因为 stringstreamMoveConstructible

    【讨论】:

    • 我认为如果没有std::move(),即使在 C++11 中也无法编译。
    • @PetrPervukhin:为什么?根据 27.8.6 [stringstream.cons],basic_stringstream 有一个有效的、可访问的移动构造函数,它将用于将ss 移出foo。是否还有其他原因导致代码无效 C++11?
    • 我可以说C++03,如果A类中没有复制构造函数,你不能写A a = A(),即使编译器可以应用复制构造函数省略。所以我不确定在这个例子中编译器是否可以用移动构造替换复制构造。
    • 对不起。我在 Coliru 试过,效果很好。所以我对谷歌和 SO 的下一个问题将是“为什么?”。 =)
    • @PetrPervukhin:请参阅open-std.org/jtc1/sc22/wg21/docs/papers/2002/… 了解基本原理。
    【解决方案2】:

    您不能从函数中按值返回流,因为这意味着您必须复制流。 C++ 流不可复制。

    【讨论】:

    • 我可能问错了问题 - 但为什么我不能复制流?
    • @Hooked 流副本的语义并不明显。当您写入一个副本时,写入是否也应该发生在另一个副本中?当你关闭一个流时,另一个也应该关闭吗?当您更改一个流的语言环境时,另一个是否也应该更改?在正确的程序中,您不应该需要来复制流。
    【解决方案3】:

    老问题,但我相信实现您想要的正确方法是使用 stringstream::str 方法,该方法返回一个字符串对象,其中包含流缓冲区中当前内容的副本。

    这是string str() const; 的示例。

    std::string foo() {
        stringstream ss;
        ss << "add whatever you want to the stream" << 12 << ' ' << 13.4;
        return ss.str();
    }
    
    int main() {
        std::cout << foo();
        return 0;
    }
    

    哪个打印:

    add whatever you want to the stream 12 13.4 
    

    【讨论】:

    • 非常感谢您实际帮助我们解决问题! :D
    【解决方案4】:

    虽然它在 C++03 中不起作用,但它应该在 C++11 中起作用。但是,当前的编译器可能仍然存在问题(由于缺乏完整的 C++11 兼容性),例如上述代码在 g++ 4.6.1 中无法编译

    【讨论】:

      【解决方案5】:

      在 C++03 中,您必须通过非常量引用将字符串流作为参数传递,或者只返回结果字符串 (ss.str()),因为您无法复制流。

      【讨论】:

        【解决方案6】:

        您必须包含sstream 并使用std::stringstream 而不是stringstream

        【讨论】:

          猜你喜欢
          • 2016-10-27
          • 2010-12-14
          • 2014-12-07
          • 2014-11-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多