2

Defining a class with the template generics is not letting me compile this class.

I have the following three files:

Class Definition:

#ifndef _myclass_h
#define _myclass_h

template <typename ValueType>
class myClass {
public:
    myClass();
};


#endif

Class Implementation:

#include "myClass.h"

template <typename ValueType>
myClass<ValueType>::myClass() { }

And the test file:

#include "myClass.h"

int main() {
    myClass<int> cls;
    return 0;
}

I'm compiling it on a MacBook Air (M1, 2020) running a MacOs Big Sur version 11.6 (20G165).

And when running this command:

g++ -std=c++11 -o testMyClass myClass.cpp testMyClass.cpp

I'm getting this error:

Undefined symbols for architecture arm64:
  "myClass<int>::myClass()", referenced from:
      _main in testMyClass-595230.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [testMyClass] Error 1

It seems that for some reason the compiler is not able to find the class constructor definition in myClass.cpp. If I take the template header in all of the classes and make the proper adaptations, the class is compiled.

Does anyone have a clue on how to solve that?

Dan
  • 127
  • 9
  • "If I take the template header in all of the classes and make the proper adaptations" - What does this mean? Sounds like that is the solution... – John3136 Nov 05 '22 at 06:52
  • I mean that when I don't use the template, it all works, so I could isolate the problem to the templates. – Dan Nov 05 '22 at 06:52
  • @Dan Yes templates should generally be implemented in header files. Also it is a linker error. – Jason Nov 05 '22 at 07:08

1 Answers1

0

I was able to implement the idea suggest here by doing the following.

In myClass.cpp I commented out the inclusion, ending up with:

/* #include "myClass.h" */

template <typename ValueType>
myClass<ValueType>::myClass() { }

And included myClass.cpp to myClass.h, like this (last line):

#ifndef _myclass_h
#define _myclass_h

template <typename ValueType>
class myClass {
public:
    myClass();
};


#endif
#include "myClass.cpp"

Aesthetically, I consider this to be an ugly solution, but it works.

Dan
  • 127
  • 9
  • Including source files(.cpp) should be usually be avoided. Implementing the template in the header is the best way to go. – Jason Nov 05 '22 at 07:13