如何为运算符<<创建C ++模板?

时间:2013-07-26 22:50:05

标签: c++ templates polymorphism

在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;
}

我正在尝试编译&amp;运行它:

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<<实现,但我不知道如何解决这个问题。

感谢。

2 个答案:

答案 0 :(得分:1)

您应该在头文件中定义模板,在这些文件中声明它们,以便编译器和链接器可以看到定义。

答案 1 :(得分:0)

尝试在声明中制作const Value* const ...