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.
Why does the addition of the extern
keyword clear warning 1 (see above)?
I assume, you are compiling your code with CLang? (To the best of my knowledge, it is CLang warning, unless g++ started to emit it as well).
On any rate, the answer to the question as asked (I only have to assume that OP understands everything else) is the simple fact that template class DirectiveHandler<double>;
- which is implicit template instantiation definition, which produces vtbl
s and such. (The fact that the warning is emitted for .cpp
file might be actually a bug, but OP doesn't ask about it).
On the other hand, extern template class DirectiveHandler<double>;
is not a definition. It is a declaration, which doesn't on itself trigger vptr
's generation - and thus you see no warning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With