2013-07-26 5 views
2

에 대한 C++ 템플릿을 만드는 방법 C++에서 operator<<에 대한 std::set의 템플릿 버전을 작성하려고 했으므로 포함 된 값 유형의 각 순열에 대해 하나씩 쓸 ​​필요가 없습니다.연산자 <<

나는 utils.h 나의 헤더를 정의 :

#ifndef UTILS 
#define UTILS 

#include <ostream> 
#include <set> 

template <typename T> 
std::ostream &operator<<(std::ostream &os, const std::set<T> &tgt); 

template <typename T> 
inline std::ostream &operator<<(std::ostream &os, 
           const std::set<T> *tgt) { 
    return os << *tgt; 
} 

#endif 

구현은 utils.cpp에 있습니다

#include "utils.h" 

template <typename T> 
std::ostream &operator<<(std::ostream &os, const std::set<T> &tgt) { 
    os << "{"; 
    bool first = true; 
    for (typename std::set<T>::const_iterator i = tgt.begin(); i != tgt.end(); 
     i++) { 
    if (!first) { 
     os << ", "; 
    } else { 
     first = false; 
    } 
    os << i; 
    } 
    os << "}"; 
    return os; 
} 

내 시도는 cout.cpp에서 사용하는 : 나는 시도하고

#include <iostream> 
#include <set> 
#include "utils.h" 

class Value { 
public: 
    const int value; 
    Value(const int value) : value(value) {} 
}; 

std::ostream &operator<<(std::ostream &os, const Value &tgt) { 
    os << "Value(" << tgt.value << ")"; 
    return os; 
} 

inline std::ostream &operator<<(std::ostream &os, const Value *tgt) { 
    return os << *tgt; 
} 

int main(const int argc, const char **argv) { 
    std::cout << argc << std::endl; 
    std::cout << *argv << std::endl; 
    Value v(10); 
    std::cout << v << std::endl; 
    Value *w = &v; 
    std::cout << *w << std::endl; 
    std::set<const Value *> vs; 
    vs.insert(w); 
    vs.insert(&v); 
    Value x = Value(12); 
    vs.insert(&x); 
    std::cout << vs << std::endl; 
    std::set<const Value *> *p = &vs; 
    std::cout << p << std::endl; 
    return 0; 
} 

을 컴파일하려면 & ru N이와 함께 :

clang++ -c utils.cpp 
clang++ -o cout cout.cpp utils.o 
./cout 

clang++가 발생했다는 오류는 다음과 같습니다

tmp/cout-6e3988.o: In function `main': 
cout.cpp:(.text+0x24d): undefined reference to `std::ostream& operator<< <Value const*>(std::ostream&, std::set<Value const*, std::less<Value const*>, std::allocator<Value const*> > const&)' 
/tmp/cout-6e3988.o: In function `std::ostream& operator<< <Value const*>(std::ostream&, std::set<Value const*, std::less<Value const*>, std::allocator<Value const*> > const*)': 
cout.cpp:(.text._ZlsIPK5ValueERSoS3_PKSt3setIT_St4lessIS5_ESaIS5_EE[_ZlsIPK5ValueERSoS3_PKSt3setIT_St4lessIS5_ESaIS5_EE]+0x19): undefined reference to `std::ostream& operator<< <Value const*>(std::ostream&, std::set<Value const*, std::less<Value const*>, std::allocator<Value const*> > const&)' 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

나는 그것을 연결하는 동안 적절한 operator<< 구현을 찾는 아니에요 이해하지만 내가 어떻게이 문제를 해결하는 방법에 대한 이동하는 아무 생각이 없다 .

감사합니다.

+0

당신은 [이] 한 번 봐 (http://kuhllib.com/2012/01/22/source-organization-of-templates을 할 수 있습니다 ... 그것은 당신의 선언에 const Value* const 만드는 시도 /). –

+1

표준 C++ 컨테이너에는 출력 연산자가 없다는 것은 귀찮은 일이지만 자신을 정의하는 것은 좋은 생각이 아닙니다. 수행하면 다른 사람들도이를 수행 할 수 있으며 하나의 정의를 위반하게됩니다 규칙. 또한 표준 컨테이너에서 작업하는 연산자를 정의한 경우 정의한 내용이 포함 된 경우에만 허용되는 'std' 네임 스페이스에 정의해야합니다. –

+1

'os << i;'이터레이터를 출력하려고합니까? :) –

답변

1

컴파일러와 링커가 정의를 볼 수 있도록 헤더 파일에 템플릿을 정의해야합니다.

0

+0

어떤 선언에? – oconnor0

+0

@ oconnor0 위의 연산자 오버로드에서'const Value *'를 사용합니다 ... 'const Value * const'로 전환하려고합니다. – Mattingly