【发布时间】:2019-06-05 13:42:27
【问题描述】:
代码
我有以下 2 个类的 sn-ps,带有单独的源文件和头文件。派生类是一个模板类。
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 的 sn-p 我有以下警告:
warning: explicit template instantiation DirectiveHandler<double> will emit a vtable in every translation unitwarning: instantiation of function DirectiveHandler<double>::operator() required here, but no definition available
如果将 template class DirectiveHandler<double> 更改为 extern template class DirectiveHandler<double>;,则两个警告都会消失。我明白为什么要清除警告 2,因为模板类位于 handler.cpp 中。我也看不到它是如何清除警告 1 的。
问题
为什么添加 extern 关键字会清除警告 1(见上文)?
【问题讨论】:
-
因为现在你没有明确的模板实例化定义,只有声明。
-
@YSC,这个关闭肯定是不正确的。 OP在问一个完全不同的问题!我现在重新打开它。
-
@SergeyA 然而,CNR。这就是为什么我们要求minimal reproducible example。
-
@YSC,首先,CNR 不同于副本。其次,您的复制尝试显然不正确 - OP 有多个文件和翻译单元,而您只有一个。我也有一种感觉 OP 正在使用 CLang,如果我是正确的,这是原始问题中缺少的一部分。
-
@YSC 什么? OP 询问为什么添加
extern会删除警告。和dup有什么关系?我完全看不出你的推理。不幸的是,由于 OP 似乎对这个问题没有我那么感兴趣,所以我将避免进一步交谈,也不会对这个问题采取任何进一步的行动。
标签: c++