通常,模板是在头文件中实现的(正如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()
创建类的实例时,仅通过构造类就得到了错误,而没有调用任何方法。
修改 该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()
的情况下,如何查找为什么不使用方法链接时才需要它的原因(这在我的实际代码中就是这样)。