代码
我有以下两个类的片段,分别有独立的源文件和头文件。派生类是一个模板类。
handler.h
class BaseHandler {
public:
BaseHandler(){}
BaseHandler(const std::string& directive);
virtual ~BaseHandler();
virtual bool operator()();
private:
const std::string m_directive;
};
template<typename C>
class DirectiveHandler : public BaseHandler {
public:
DirectiveHandler(const std::string& directive);
~DirectiveHandler();
bool operator()() override;
private:
std::vector<C> m_configurations;
};
handler.cpp
#include "handler.h"
BaseHandler::BaseHandler(const std::string& directive) : m_directive(directive) {};
BaseHandler::~BaseHandler(){};
template<typename C>
DirectiveHandler<C>::DirectiveHandler(const std::string& directive) :
BaseHandler(directive) {};
template<typename C>
bool DirectiveHandler<C>::operator()(){ return true; };
main.cpp
#include "handler.h"
template class DirectiveHandler<double>; //explicit template instantiation
int main(int argc, char *argv[]){
....
根据我的理解,在定义模板之后需要实例化它,这可以通过隐式(省略
template class DirectiveHandler<double>;
)或显式的方式来实现。我假设隐式实例化失败是因为在相应的源文件和头文件中分离了定义和声明。
使用上述main.cpp片段时,我得到以下警告:
警告:显式模板实例化DirectiveHandler<double>将在每个翻译单元中生成一个虚函数表
警告:在此处需要实例化函数DirectiveHandler<double>::operator(),但没有可用的定义
template class DirectiveHandler<double>
更改为extern template class DirectiveHandler<double>;
,这两个警告都会消失。我理解为什么警告2被清除了,因为模板类位于handler.cpp中。但我不明白它如何同时清除警告1。问题:
为什么添加
extern
关键字会清除警告1(见上文)?
extern
会消除警告。这与dup有什么关系?我完全看不出你的推理。不幸的是,由于OP似乎对这个问题的兴趣不如我,我将避免进一步的交谈和任何对这个问题的进一步行动。 - SergeyA