模板类实例化如何与类继承协同工作
How does template class instantiation work together with class inheritance?
代码
我有以下两个类的片段,它们有一个单独的源文件和头文件。派生类是一个模板类。
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;
};
处理程序.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的片段,我有以下警告:
warning: explicit template instantiation DirectiveHandler<double> will emit a vtable in every translation unit
warning: 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(见上文)?
我想,您是在用CLang编译代码吗?(据我所知,这是CLang警告,除非g++也开始发出警告)。
无论如何,这个问题的答案(我只需要假设OP理解其他一切)是一个简单的事实,template class DirectiveHandler<double>;
-这是一个隐含的模板实例化定义,它产生了vtbl
s等等。(为.cpp
文件发出警告的事实实际上可能是一个错误,但OP并没有对此进行询问)。
另一方面,extern template class DirectiveHandler<double>;
不是一个定义。它是一个声明,本身不会触发vptr
的生成,因此您不会看到任何警告。
- 我不明白参数和参数如何协同工作
- Qt C++括号匹配和突出显示当前线路功能无法协同工作
- scanf() 语句中"%*[^n]"的格式字符串指示什么?分配抑制器 (*) 和否定扫描集 ([^) 如何协同工作?
- Emrun 和无头铬 - 如何让这两者协同工作?
- 如何编译Freetype(2)和Harfbuzz(带有Visual studio)使它们协同工作?
- 模板类实例化如何与类继承协同工作
- 如何将RegisterDragDrop,RoInitialize组合在一个线程中协同工作
- 如何让助推upgrade_to_unique_lock+condition_variable协同工作
- 将 Boost.Serialization 直接与虚拟钻石继承一起工作
- Fruchterman-Reingold的吸引力是如何与Boost图库协同工作的
- 如何使Ws2_32.lib与针对Windows 8.1的VS 2013项目协同工作
- 如何在C++中使一个void函数与另一个void功能协同工作
- std::transform 和 std::p lus 如何协同工作
- 无法让 cgal 和 hdf5 协同工作
- std::ref 和交换功能似乎不能很好地协同工作
- 类的详细信息:设计一组协同工作的类时出错
- 如何使这两个模板类协同工作?(C++中的属性)
- 有什么方法可以让谷歌测试框架与Visual Studio 6协同工作吗
- c++如何使双语句sql与OLEDB协同工作
- 为什么重载在Java中与继承一起工作