2013-04-02 6 views
5

STL 컨테이너를 인쇄하려고합니다. 내가하려고하는 것은 구분 기호로 구분 된 컨테이너의 elemets를 출력하는 것이다. 그러나 몇 가지 문제가 발생했습니다. VC++ostream 연산자 오버로드 템플릿

ostream& operator<<(ostream& o, const vector<string>& v) { 
    copy(v.begin(), v.end(), std::ostream_iterator<string>(o,",")); 
} 

int main() 
{ 

    vector<string> s_v; 
    s_v.push_back("one"); 
    s_v.push_back("two"); 

    cout << s_v; 

} 

그램 ++ (mingw32에 GCC 버전 4.4.0) 대

1 g ++는 그것에게 잘 작동 컴파일 할 수 있습니다. VC++ (Visual Studio 9)는이 코드를 컴파일 할 수 없습니다.

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion) 
1>  c:\program files (x86)\microsoft visual studio 9.0\vc\include\ostream(653): could be 'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)' 
1>  with 
1>  [ 

왜 그렇습니까? 이 코드가 불법입니까? 아니면 VC++ beign VC++일까요?


2. 사용하지 않는 템플릿 변수 휴식 컴파일.

지금은 (그냥 거기 앉아, 사용하지 않을)이 같은 ostream에 템플릿을 추가

template <typename T> // <----- Here 
ostream& operator<<(ostream& o, const vector<string>& v) { 
    copy(v.begin(), v.end(), std::ostream_iterator<string>(o,",")); 
} 

int main() 
{ 

    vector<string> s_v; 
    s_v.push_back("one"); 
    s_v.push_back("two"); 

    cout << s_v; 

} 

GCC는 더 이상 연산자와 일치 할 수 없습니다.

error: no match for 'operator<<' in 'std::cout << s_v' 

and a lot more candidates... 

이유는 무엇입니까? 템플릿은 사용되지 않습니다. 그건 중요한거야?


편집 :이 해결된다. 나는 o를 돌려줘야했다.

3. 템플릿 유형을 사용 알고있는 경우에 사용 된 템플릿

template <typename T> 
ostream& operator<<(ostream& o, const vector<T>& v) { 
    copy(v.begin(), v.end(), std::ostream_iterator<T>(o,",")); 

    return o; // Edited 
} 

int main() 
{ 

    vector<string> s_v; 
    s_v.push_back("one"); 
    s_v.push_back("two"); 

    vector<int> i_v; 
    i_v.push_back(1); 
    i_v.push_back(2); 

    cout << s_v; 
    cout << i_v; 
} 

. g ++는 컴파일 할 수 있지만 예외로 종료됩니다.

terminate called after throwing an instance of 'std::bad_cast' 
    what(): std::bad_cast 

VC++는 앉아 GCC는이 모든 걸 지켜보고있다. 그들 중 어떤 것도 컴파일하지 않습니다.

누군가 나를 위해이 사실을 분명히 해줄 수 있습니까? 고맙습니다.

+0

std 네임 스페이스에서 연산자를 정의하십시오. 차이점을 볼 수 있습니다 – PiotrNycz

+0

컴파일러가 템플릿 인수의 유형을 추론 할 수없는 경우 직접 제공해야합니다. 그러므로' void Foo() {...}'템플릿을 가지고 있다면'Foo ()'을 사용해야합니다. 분명히, 당신은 당신이 통신 수을 과대 적재 할 때 그것을 할 수 없다. 'T'를 사용할 때, 컴파일러는 타입을 추론 할 수 있기 때문에 이것이 작동합니다. – zneak

+0

또한 마지막 예제는 ideone에서 [잘 실행됩니다] (http://ideone.com/mLJcTI)입니다. 당신은'return o;'연산자를'operator <<'에 추가하려고 할 수 있습니다. 이것은'cout << s_v << i_v'를하면 프로그램을 망칠 가능성이 높습니다. – zneak

답변

관련 문제