【问题标题】:c++ class with templates compilation error带有模板编译错误的c ++类
【发布时间】:2009-10-27 14:59:20
【问题描述】:

我不是一位经验丰富的 C++ 程序员,我在编译时遇到了问题。我有一个使用模板的堆类:

template <class T>
class Heap
{
  public:
    Heap(const vector<T>& values);

  private:
    vector<T> d;

  // etc.
};

然后在单独的实现文件中:

template <class T>
Heap<T>::Heap(const vector<T>& values)
{
d = values;

for (unsigned int i = d.size()-1; i > 0; i--) Heapify(ParentIndex(i));
}

// ... more implementation code ...

最后是 main.cc 文件:

int main (int argc, char *argv[])
{
  vector<int> in;
  unsigned int i;

  while (cin >> i) in.push_back(i);
  Heap<int> h = Heap<int>(in);

  return 0;
} 

我得到这些编译错误:

g++ -Wall -I/opt/local/include -c -o main.o main.cc
g++ -Wall -I/opt/local/include -c -o heap.o heap.cc
g++ -Wall -o heap main.o heap.o
Undefined symbols:
  "Heap<int>::Heap(std::vector<int, std::allocator<int> > const&)", referenced from:
      _main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [heap] Error 1

为什么不能编译?我认为链接器说它找不到构造函数,但我知道它创建了目标文件。

【问题讨论】:

  • 堆构造函数是否定义在单独的文件中?这对模板不太适用。

标签: c++ class templates linker


【解决方案1】:

需要在头文件中 100% 定义模板。如果您在 .cc / .cpp 文件中有 Heap&lt;T&gt; 实现,那就是问题所在。将所有代码移至头文件,它应该可以解决您的问题。

【讨论】:

  • 您还可以通过#将实现包含到标题中来保持它们物理上的分离
  • @Cogwheel,是的,但包含 .cpp 文件通常是错误的代码登录。我更喜欢 1) .h 中的所有内容或 2) 将代码放入 .inl 文件中。不同的文件扩展名使意图更清晰
  • @JaredPar,是的。我通常使用 .inl。
  • 嗯,这是一个很好的经验法则,但在特定情况下(当它们仅在这些文件中使用时),我确实在 .cpp 文件中定义了一些模板。不过,我需要像 litb 这样拥有更好世界的人来提供完整的解释:)
【解决方案2】:

根据 C++ 标准,您可以这样使用 export 关键字:

export template<typename foo>...

但是,大多数编译器不支持这一点。 C++ FAQ 有更多信息:http://www.parashift.com/c++-faq-lite/templates.html#faq-35.14

请参阅 JaredPar 的答案,了解实际可靠的内容。

【讨论】:

  • “export”是标准委员会在没有经验的情况下坚持的事情之一,它表明了这一点。它很难实现,而且似乎也没有做任何人真正想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多