Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

undefined reference to `vtable for a template

I have a template class which inherits from an interface class and therefore has virtual functions

//abstract.h
class Abstract {
virtual void abc();
Abstract();
}
//Abstract.cpp
Abstract::Abstract()
{ //do some init}

//concrete.h
class Impl {
public:
    void abcImpl();
};

template<typename T>
class Concrete : public Abstract, public T {
virtual void abc();
};
template<typename T>
Concrete<t>::abc()  { static_cast<T>(*this).abcImpl(); }

//concrete.cpp
void Impl::abc() { std::cout << "abc"; }

Used here

//foo.cpp
Concrete<Impl> *var1 = new Concrete<Impl>();

At link time, I get an error undefined reference to `vtable for Abstract'

In the past this error indicated that the complier couldnt find a place to put a vtable because there was no cpp file associated with that class. In other words, it puts the vtable where it first finds the first non-virtual definition of any member function. But this is puzzling because. 1. Im not sure why it complains about Abstract - Abstract actually has a cpp 2. Maybe error msg actually means Concrete? But Concrete cannot be in a cpp file because its templatized. So how does in general resolve this issue when dealing with a template class that also has virtual functions?

like image 582
excalibur Avatar asked Feb 10 '12 21:02

excalibur


1 Answers

The problem might be due to the abc() method not declared as pure virtual. For example, GCC will use abc() as the key method for vtable placement, because it is the first non-inline, non-pure virtual method declared in the class (details: http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html). If you declare abs() pure virtual, it should place vtable in Abstract.cpp where the constructor is defined.

like image 76
Alexey Kukanov Avatar answered Oct 21 '22 16:10

Alexey Kukanov