【问题标题】:Linking templates with g++使用 g++ 链接模板
【发布时间】:2010-12-22 00:00:22
【问题描述】:

我正在使用模板在 C++ 中实现哈希表和链表(没有 STL - 不要问),并且在将它们与 g++ 链接时遇到了问题。如果我 #include 我所有的 .cpp 文件一起,一切正常,所以我的代码肯定有效,只是链接让我绊倒。

我阅读了the bit in the GCC manual about template instantiation,但不知道如何应用它。

我的问题: 我的哈希表有 HashMap<T>HashEntry<T><T> 是值 - 我的键是 std::strings)。我的链接列表有LinkedList<T>Node<T>(其中<T> 是值)。

在我的哈希图中,我有:

template <class T> class HashMap {
    ...
    private:
        LinkedList< HashEntry<T> >** buckets;
 }

这给了我一个HashEntry&lt;T&gt;s 的链接列表。

在一个单独的文件中,我有我的 Linked List 类声明:

template <class T>
    class Node {
        ...
        private:
             T data;
}

template <class T> class LinkedList {
     ...
     private:
     Node<T> * first;
}

然后,当我尝试链接所有内容时(使用g++ -c -frepo *.cpp 编译后),我得到:

g++ -frepo -o app LinkedList.o HashMap.o
[...unrelated errors about not having a main method - they go away when I link that in]
HashMap.o: In function `HashMap<int>::~HashMap()':
HashMap.cpp:(.text._ZN7HashMapIiED1Ev[HashMap<int>::~HashMap()]+0x65): undefined reference to `LinkedList<HashEntry<int> >::~LinkedList()'
HashMap.o: In function `HashMap<int>::insert(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)':
HashMap.cpp:(.text._ZN7HashMapIiE6insertESsi[HashMap<int>::insert(std::basic_string<char,     std::char_traits<char>, std::allocator<char> >, int)]+0xff): undefined reference to     `Node<HashEntry<int> >::setData(HashEntry<int>)'

谷歌搜索,我看到了声明我的程序使用的显式模板类型的建议。这适用于HashMapHashEntry(我添加了(template class HashMap&lt; int &gt;template class HashEntry&lt; int &gt;

但是,我不知道如何使 LinkedListNode 类工作,因为模板实例属于 HashEntries&lt;int&gt;。但是,我不能把它放到LinkedList.h 文件中,因为我的哈希表是#included。我也无法获得为其工作的高级/外部声明。

我确信我缺少一些相当简单的东西来完成所有这些工作。有什么建议吗?

【问题讨论】:

  • 你的LinkedList析构函数在任何地方都有定义吗?还是Node&lt;...&gt;::setData()
  • 可能不相关,但有什么理由你不使用 make、waf、SCons 等?
  • @kotlinski:正确,我的 HashMap 使用 LinkedList(用于链接),我的文件顶部有一个 #include "LinkedList.h"
  • @robert:我的 ~LinkedList() 和 setData 在 .cpp 文件 (template &lt;class T&gt; LinkedList&lt;T&gt;::~LinkedList()) 中。同样,如果我 #include 所有我的 .cpp 文件一起编译。没有构建系统 - 现在只是试图让它从头开始工作。

标签: c++ templates linker g++


【解决方案1】:

如果您正在制作模板类,将它们放在 .cpp 文件中并单独编译不是一个好主意。正确的方法是将它们放在 .h 文件中(包括声明和定义),并将它们包含在您需要的地方。

原因是除非定义了模板参数,否则模板实际上不会被编译。

(故意避免提及 export 关键字。)

【讨论】:

  • 你知道,export 的东西在 C++0x 中被删除了......哦,对了:P +1
  • 谢谢 - 我想我会成功的。现在我只是将我的 .cpp 文件包含到 .h 文件中。这是一件好事吗,还是我真的应该在我的类声明中移动代码?
  • @Taj Morton 将它移到类声明中。包含 cpp 文件通常被认为是错误的格式。
【解决方案2】:

看起来您正在 LinkedList.cpp 中定义模板类成员。模板通常需要在 .h 文件中完全定义(而不仅仅是声明)。有关解决此问题的方法,请参阅storing C++ template functions in a .cpp file. 但我会避免使用它——它会导致更多的问题而不是它的价值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多