【问题标题】:What is wrong with stringstream str function?stringstream str 函数有什么问题?
【发布时间】:2014-03-07 06:13:35
【问题描述】:

我尝试使用以下代码概括流对象:

#include <iostream>
#include <vector>
#include <sstream>
#include <iterator>

using namespace std;

template<class T, class U>
T& operator<<(T& os, vector<U> vec)
{
    vector<string>::iterator begin = vec.begin();
    vector<string>::iterator end = vec.end();
    for (; begin != end; ++begin)
        os << *begin << " ";
    return os;
}

int main()
{
    vector<string> things({
        "car", "truck", "rabbit"
    });

    ostringstream oss;
    oss << things << endl;
    copy(oss.str().begin(), oss.str().end(), ostream_iterator<char>(cout, ""));
}

现在它适用于cout &lt;&lt; thingsstring str = oss.str(); copy(str.begin() ...,但不适用于oss.str().begin()。据我了解,str() 返回一个 string 对象,其中包含流当前内容的副本。那么为什么我们需要复制它两次,一次从str() 复制一次,一次在字符串对象的初始化中呢?这个问题与使用c_str()不同。

以下也有效:

string::iterator begin = oss.str().begin();
string::iterator end = oss.str().end();
copy(begin, end, ostream_iterator<char>(cout, ""));

【问题讨论】:

    标签: c++ string stl stringstream


    【解决方案1】:

    据我了解,str() 返回一个字符串对象,其中包含 流的当前内容。

    没错。这就是你问题的答案。因为str() 返回一个副本,所以对oss.str() 的两次调用会产生两个完全不同的副本(即两个不同的字符串对象)。两个字符串对象的迭代器不兼容,因为它们不是来自同一个字符串。将来自两个完全不同字符串的两个迭代器传递给期望它们来自同一范围的算法(例如 std::copy)是未定义的行为。

    你不会指望这会起作用吧?

    std::string str1 = oss.str();
    std::string str2 = oss.str();
    std::copy(str1.begin(), str2.end(), ostream_iterator<char>(cout, ""));
    

    作为对您的修改的回应,“以下也有效:”。如果这行得通,那纯属巧合。这些迭代器在创建它们的语句结束时都是无效的,因为它们指向的字符串不再存在。您在调用std::copy 时使用它们是未定义的行为。

    【讨论】:

      猜你喜欢
      • 2013-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多