Code
I have the following snippets of 2 classes with a separate source and header file. The derived class is a template class.
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[]){
....
To my understanding I need to instantiate the template after it has been defined, this can happen either implicitly (leave out template class DirectiveHandler<double>;
) or explicitly.
I'm assuming that implicit instantiation fails due to the separation of definition and declaration in the respective source and header file.
With the snippet of main.cpp above I have the following warnings:
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
If change template class DirectiveHandler<double>
to extern template class DirectiveHandler<double>;
both warnings dissapear. I do understand why warning 2 is cleared, because the template class resides in handler.cpp. I fail to see how it clears warning 1 as well.
Question
Why does the addition of the extern
keyword clear warning 1 (see above)?