stringstream str函数有什么问题?

use*_*320 0 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, ""));
}
Run Code Online (Sandbox Code Playgroud)

现在,它与工作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, ""));
Run Code Online (Sandbox Code Playgroud)

Ben*_*ley 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, ""));
Run Code Online (Sandbox Code Playgroud)

为了回应您的编辑,"以下也有效:".如果这样可行,那纯粹是巧合.这些迭代器在创建它们的语句的末尾都是无效的,因为它们指向的字符串不再存在.您在调用中使用它们std::copy是未定义的行为.