stringstream str函数有什么问题?

时间:2014-03-07 06:13:35

标签: c++ string stl stringstream

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

#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 << thingsstring str = oss.str(); copy(str.begin() ...,但不适用于oss.str().begin()。据我所知,str()返回一个字符串对象,其中包含当前流内容的副本。那么为什么我们需要将它复制两次,一次是从str()复制一次,一次是在字符串对象的初始化中复制一次?此问题与使用c_str()不同。

以下也有效:

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

1 个答案:

答案 0 :(得分:7)

  

据我所知,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调用中对它们的使用是未定义的行为。