Question

I am currently implementing generic string related template class that does a lot of complex things. To optimize compile times I thought about implementing the functionality inside translation unit instead of header file and then instantiating types for UTF-8, UTF-16 and UTF-32. The bottleneck that I'm trying to figure out is, if it's possible to split the template class instantiating into multiple translation units, since what one group of member functions does is very complex code and it would make a lot of sense to separate that into it's own translation unit.

Here's example what I'm trying to do:

example.h

template <typename T>
class Example
{
public:
  void test1();
  void test2();
};


example_test1.cpp

template <typename T>
void Example::test1()
{
  ...
}

template class Example<uint8_t>;
template class Example<uint16_t>;
template class Example<uint32_t>;


example_test2.cpp

template <typename T>
void Example::test2()
{
  ...
}

template class Example<uint8_t>;
template class Example<uint16_t>;
template class Example<uint32_t>;


Obvious (and hacky) solution would be to create mini "unity build" that includes example_test1.cpp and example_test2.cpp, but that's bit cheap way to do it and there would be only one translation unit. I wonder if there's any better solution?

EDIT: And please, if your answer is to "put it inside header", then don't. That's not helping. The idea here is to optimize compile time by removing stuff from headers that doesn't need to be there. Our compile time is already very high because of the excessive usage of templates in headers. And also I don't need tips about how to optimize compile times using other ways. I know how to use precompiled headers, etc. If I could just get answers that are on topic.

Was it helpful?

Solution

What you are trying to do is called explicit instantiation and the correct syntax is following:

template class Example<uint8_t>;
template class Example<uint16_t>;
template class Example<uint32_t>;

If you really need to distinguish the methods into separate files, I would create a file example_instances.cpp for the code above, just to have it only once in the sources for better manageability. The code would be organized in the following way:

example.h

template <typename T>
class Example
{
public:
  void test1();
  void test2();
};

example_test1.cpp

#include "example.h"

template <typename T>
void Example::test1()
{
  ...
}

#include "example_instances.cpp"

example_test2.cpp

#include "example.h"

template <typename T>
void Example::test2()
{
  ...
}

#include "example_instances.cpp"

If you are discouraged from including .cpp files, put the instances into a separate header file. However, this one should be included after implementation unlike common header files (explicit instantiation of function template fails (g++)).

OTHER TIPS

So you are trying to do compiller job. There is no instantation of member function of template classes if there is no call. So it is useless to define them in different translation units. Compiller do it without you and better than you. My advice is to put all your code into header file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top