2014-03-07 2 views
0

나는 다음 코드를 사용하여 스트림 개체에 대한 일반화하려고 : stringstream str 함수의 문제점은 무엇입니까?

#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, "")); 
} 

가 지금은 oss.str().begin()cout << thingsstring str = oss.str(); copy(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, "")); 

답변

7

는 STR() 스트림의 현재 내용의 사본 String 오브젝트를 돌려줍니다.

맞습니다. 그리고 그것은 여러분의 질문에 대한 해답입니다. 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로 전화를 걸 때 사용하면 정의되지 않은 동작입니다.

관련 문제