【问题标题】:C++ template, linking error [duplicate]C ++模板,链接错误[重复]
【发布时间】:2010-11-24 03:34:30
【问题描述】:

我在调用我拥有的模板类时遇到问题。 我声明了一个新的类型名称Array,它是一个模板;

在 .hpp 文件中:

template <typename T>
class Array
{
public:
   Array();
};

.cpp 文件中:

template <typename T>
Array<T>::Array()
{
//Do something
}

主要:

Array<int> arr;

我收到链接错误:未解析到 ctor 的外部符号。

有什么想法吗?

【问题讨论】:

标签: c++ templates linker


【解决方案1】:

模板函数,包括成员函数,必须完全写在头文件中。这意味着如果你有一个模板类,它的实现必须完全在一个头文件中。这是因为编译器需要访问整个模板定义(而不仅仅是签名)才能为模板的每个实例化生成代码。

【讨论】:

  • 是的,它奏效了。您能否添加更多解释,为什么需要在标题中定义所有内容?另外我添加的实现都是在“endif”之前添加的,对吧?
  • 正确。有关原因的详细解释,请参阅 parashift.com/c++-faq-lite/templates.html#faq-35.12 和以下问题 35.13,moonshadow 链接到。
  • 技术上这不是一个要求。您可以在某个编译单元中显式实例化模板并在其他地方使用该模板,但这需要相当多的手动内务处理(为项目中使用的每种新类型添加显式实例化),甚至可能使其变得不可能(如果您必须使用未知类型)。
  • 这里不仅使用模板作为通用代码。模板也用于编码器生成器,您可以确切地知道需要哪些变体(例如“大端”、“小端”)
  • 你打算合并 cmets 吗?因为这样回答不是很好。
【解决方案2】:

把模板声明和模板函数都放进去 头文件中的定义。大多数 C++ 编译器都不容易支持模板的单独编译模型,

【讨论】:

    【解决方案3】:

    如果模板化函数的定义在使用时不可见(即不在标头或同一个 CPP 文件中),则需要tell the compiler which instantiations to make

    【讨论】:

      【解决方案4】:

      您在这里遇到的问题是您在 .cpp 文件中隐藏了构造函数的定义。此定义适用于 所有 类型 T,包括您使用的 T 作为 int,但实际上没有提供任何定义,因为它仍然只是一个声明。
      链接器找不到符号Array&lt;int&gt;::Array()

      现在,您可以像这样添加一行:

      Array<int> arr1;
      

      到 Array.cpp 文件的末尾,这使得编译器 实例化 成为链接器正在寻找的正确定义。但是,这仅提供一个定义,即Array&lt;int&gt; 的定义,没有其他定义。

      此解决方案将有效,直到您需要不同模板参数的Array,例如double,此时您需要添加:

      Array<double> arr2;
      

      到您的 Array.cpp 文件的末尾 - 现在您可以看到这是不可持续的!

      如果您需要 C++ 来处理您将来可能需要的 任何 类型,现在是时候将 ctor(以及可能所有其他成员函数)的定义移到标头(并删除 .cpp 文件,因为它不会留下任何东西)。

      【讨论】:

        【解决方案5】:

        如上所述,在C++模板中,新方法的过程是由编译器在编译时执行的,问题是它需要知道那段时间的所有定义,所以所有的类/函数声明必须是ar h 或 hpp 文件。

        【讨论】:

          【解决方案6】:

          另一个答案,只编译您的 .cpp 文件(不是主文件)并检查目标文件的大小,然后创建一个 empty.cpp 文件,然后编译该 empty.cpp。最后比较两个目标文件的大小。您会看到它们具有相同的大小,这意味着您的 .cpp 文件对编译器来说没有任何意义,因此链接器找不到任何东西。

          【讨论】:

            猜你喜欢
            • 2010-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-16
            • 2019-06-27
            相关资源
            最近更新 更多