0

Consider the following code. A is an abstract, generic class; B both implements and specializes it. This code seems trivially correct to me, but for some reason I end up with strange linker errors.

template<typename T>
class A {
    public:
        virtual void f();
};

class B : public A<int> {
    public:
        void f() {};
};

int main(int argc, char** argv) {
    auto b = new B();
    return 0;
}

gcc output:

/tmp/ccXG2Z8A.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()'
collect2: error: ld returned 1 exit status

clang output:

/tmp/l2-2a09ab.o: In function `main':
l2.cpp:(.text+0x35): undefined reference to `operator new(unsigned long)'
/tmp/l2-2a09ab.o:(.rodata._ZTI1AIiE[_ZTI1AIiE]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
/tmp/l2-2a09ab.o:(.rodata._ZTI1B[_ZTI1B]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/tmp/l2-2a09ab.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Carl Patenaude Poulin
  • 6,238
  • 5
  • 24
  • 46

2 Answers2

1

A is not an abstract class. You should do:

virtual void f() = 0; 

to make it a pure virtual function

Asesh
  • 3,186
  • 2
  • 21
  • 31
1

From gcc output, I'll assume that your function is called foo instead of just f.

The problem is that the class A is not abstract, because you haven't declared its method as such. You would do so in this way:

virtual void foo() = 0;

But you forgot the = 0, so the linker doesn't know that the method is abstract, and is therefore looking for a function body that is not there.

rucamzu
  • 926
  • 1
  • 9
  • 16