未使用的类模板方法的未定义引用

时间:2018-12-18 12:43:12

标签: c++ templates

通常,模板是在头文件中实现的(正如Stack Overflow中的许多答案所指出的那样),因此,当编译器需要它来创建类/函数的新实例时,代码模板可供编译器使用。但是,就我而言,模板类中的某些方法只能用于特定类型,因此我的类如下所示:

类标题

#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(),因为我为这两种类型显式实例化了该类模板。在程序中使用此类模板时,只要不调用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;
}

但是,由于编译器无法为类型为func()的{​​{1}}类初始化LEC的代码,因此我无法执行char或得到一个编译器错误:

  

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

这是我的真实代码的简化。但是,在我的代码中,当我执行c.func()创建类的实例时,仅通过构造类就得到了错误,而没有调用任何方法。

  • 关于如何找出这种显然没有使用的方法为何必须进行链接的想法?
  • 有没有办法让编译器(在我的情况下,我使用的是clang ++:clang版本6.0.0-1ubuntu2)指出在代码中使用此方法的地方?
  • 否则,有人可以解释为什么这种方法(不必链接到未使用的类方法)在所提供的示例中有效,而在我的代码中却无效吗?

修改 该cmake看起来像:

LEC<char> c

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

编辑2 请避免建议诸如Why templates can only be implemented in the header file之类的答案,因为我已经知道在为新类型实例化该类时,模板必须对编译器可用。我的问题不同。为什么我要实例化一个并非所有模板实现都可用的类型,只要我不使用实例化时未为其提供模板实现的特定类方法(在示例情况下为add_library(lec_lib SHARED lec.cpp lec.h) add_executable(lec_main main.cpp) target_link_libraries(lec_main lec_lib)

编辑3 关于这是What is an undefined reference/unresolved external symbol error and how do I fix it?的副本的建议。同样,我的问题是不同的。我正在寻找答案,以说明为什么在示例中当编译器在编译主程序时func()对于编译器不可见时可以实例化LEC<char>。并且在无法完成并且需要链接LEC<char>::func()的情况下,如何查找为什么不使用方法链接时才需要它的原因(这在我的实际代码中就是这样)。

0 个答案:

没有答案