代码之家  ›  专栏  ›  技术社区  ›  apalomer

未定义对未使用的类模板方法的引用[重复]

  •  0
  • apalomer  · 技术社区  · 6 年前

    一般来说,模板是在头文件中实现的(正如堆栈溢出中指出的许多答案一样),因此当编译器需要代码模板来创建类/函数的新实例时,代码模板是可用的。但是,在我的例子中,我的模板类中的一些方法只能用于特定类型,因此我的类看起来像:

    类标题

    #ifndef LEC_H
    #define LEC_H
    
    #include <iostream>
    
    template <typename T>
    class LEC
    {
    public:
      LEC()
      {
      }
    
      void func() const;
    
      void func2() const
      {
        std::cout << "Func 2" << std::endl;
      }
    };
    
    #endif  // LEC_H
    

    cpp级

    #include "lec.h"
    
    template <typename T>
    void LEC<T>::func() const
    {
      std::cout << "Func: " << typeid(T).name() << std::endl;
    }
    
    template class LEC<float>;
    template class LEC<double>;
    

    cpp文件的最后两行允许我使用 func() 因为我显式地为这两种类型实例化了这个类模板。当我在程序中使用这个类模板时,只要不调用 函数() :

    #include "lec.h"
    
    int main()
    {
      LEC<float> a;
      LEC<double> b;
      a.func2();
      a.func();
      b.func2();
      b.func();
      LEC<char> c;
      c.func2();
      return 0;
    }
    

    但是,由于代码不可由编译器调用 函数() 为了一个 LEC 按类型分类 char ,我做不到 c.func() 否则会出现编译器错误:

    对“LEC::func()const”的未定义引用

    这是我真实代码的简化。但是,在我的代码中,当我 LEC<char> c 要创建类的实例,我会得到错误,而不调用任何方法,只通过构造类。

    • 你知道为什么这个,显然不是用过的方法,无论如何都要联系起来吗?
    • 有没有办法让编译器(在我使用clang++:clang版本6.0.0-1ubuntu2的情况下)指出这个方法在代码中的使用位置?
    • 否则,有人能解释为什么这个(不必链接到一个未使用的类方法)在提供的示例中工作,而不是在我的代码中?

    编辑 cmake看起来像:

    add_library(lec_lib SHARED lec.cpp lec.h)
    add_executable(lec_main main.cpp)
    target_link_libraries(lec_main lec_lib)
    

    因此,编译后的库与可执行文件相链接。

    编辑2 请避免提出诸如 Why templates can only be implemented in the header file 因为我已经知道当为新类型实例化类时,模板必须对编译器可用。我的问题不一样。为什么我可以实例化一个类型,而不是所有的模板实现都可用,只要我不使用在实例化时没有提供模板实现的特定类方法(在示例中 函数() )

    编辑3 关于这是 What is an undefined reference/unresolved external symbol error and how do I fix it? . 我的问题又不同了。我正在寻找关于为什么在示例中我可以实例化 LEC<char> 什么时候 LEC<char>::func() 编译器编译主程序时不可见。如果这件事办不到 L3C<char>::func() 是需要被链接的,如何在不使用方法链接的情况下找到为什么需要方法链接(这是在我的实际代码中发生的事情)。

    0 回复  |  直到 6 年前