0

I have a template class with separate declaration and implementation:

// template.hpp
template <typename T>
class Foo {
  T _data;
  void func();
};

// template.cpp
#include "template.hpp"

template <typename T>
void Foo<T>::func() {
  // Do something on _data
}

those template files will be compiled into a library, and in another cpp file I link the library and instantiate the template class as follows:

// my.cpp
#include "template.hpp"

struct MyData {
  // Some data here
};

class Bar {
  Foo<MyData> foo;
};

I get linker error when compiling my.cpp file. Is there any way to avoid the linker error by just modifying the template.hpp and template.cpp?

I don't want to move the template implementation into the header file and I can't move the MyData into template.hpp.

Tes
  • 349
  • 3
  • 12
  • 2
    Does this answer your question? [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – UnholySheep Dec 28 '19 at 23:12
  • The explicit instantiations does not work in my case as `MyData` is not seen when compiling the library. – Tes Dec 28 '19 at 23:13
  • 1
    Then you need to move the implementations into the header file. What is the reason that you don't want to do that? The compiler needs to know all definitions from the template in order to instantiate a specialization for a new type. – walnut Dec 28 '19 at 23:14
  • I will change the implementation frequently and moving implementation into the header file will increase the compilation time when building the whole project (the header is also included in many other cpp files). – Tes Dec 28 '19 at 23:16
  • That is the cost of using templates in C++, compilation times are a downside – UnholySheep Dec 28 '19 at 23:17
  • There can be improvements, but you need to be more specific rather than "something". Also modules. – Yakk - Adam Nevraumont Dec 28 '19 at 23:29
  • You can still use explicit instantiation. You just need to split `my.cpp` into two parts, one which includes the definition of `MyData`, the whole template implementation and only instantiates the template for all relevant types from the library user and one part which includes only the template definition or uses `extern template` to avoid repeated instantiation, but implements the rest of `my.cpp`. You cannot avoid re-instantiation for all relevant types if you change the implementation of the template, but you can avoid re-compilation of the remaining `my.cpp` code. – walnut Dec 28 '19 at 23:29
  • `template` is just better syntax for `#define`, it's a code generation tool. You actually *want* to recompile all .cpp files that depend on the template implementation, since it's `inline`. Either move the template implementation into the header file or wait for C++ modules. – rustyx Dec 28 '19 at 23:46

0 Answers0