在C++中,我试图为std::set
编写operator<<
的模板版本,这样我就不必为包含的值类型的每个排列编写一个模板。如何为运算符创建C++模板<<
我定义我的头为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 ñ它具有:
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<<
实现,但我不知道如何去解决这个问题。
谢谢。
你可能想看看[这里](http://kuhllib.com/2012/01/22/source-organization-of-templates /)。 –
尽管标准C++容器没有输出操作符是令人讨厌的,但定义自己并不是一个好主意:如果你这样做了,其他人也可以这样做,并且最终会违反一个定义规则。另外,如果你定义了一个在任何标准容器上工作的操作符,你需要在名字空间'std'中定义它,只有当它涉及到你定义的东西时才允许使用它。 –
'os << i;'你想输出迭代器吗? :) –