Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicit template instantiation with variadic templates

I have several template classes Impl (with some abstract methods) that are partially implemented in CPP files so that I need to explicitly instantiate my templates for the linker to find it, like this:

template class Impl<T0>;
template class Impl<T1>;
template class Impl<T2>;
...
template class Impl<Tx>;

As the number of types Tx grows, I would like to find a better way than to manually expand these lists of explicit instantiations in all necessary files. I thought I could use variadic templates for this, so I tried the following:

template <template <class> class, class...>
struct type_map;

template <template <class> class BaseT, class... Ts>
struct type_map<BaseT, std::tuple<Ts...>> {
    using type = std::tuple<BaseT<Ts>...>;
};

typedef std::tuple<T0, T1, T2> MyTypes;

And in the CPP file:

template class type_map<Impl, MyTypes>;

However, this didn't instantiate the templates as I intended (the linker complained about the missing symbols).

Is there a way to make this approach work (i.e. instantiate the template without instantiating an object of it) or a totally different approach that could solve my problem in this situation?

like image 351
fschoenm Avatar asked May 13 '14 09:05

fschoenm


People also ask

What is explicit template instantiation?

You can use explicit instantiation to create an instantiation of a templated class or function without actually using it in your code. Because this is useful when you are creating library (. lib) files that use templates for distribution, uninstantiated template definitions are not put into object (. obj) files.

What is a Variadic template C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.

What is implicit instantiation?

Implicit instantiation means that the compiler automatically generates the concrete function or class for the provided template arguments. In general, the compiler also deduces the template arguments from the function's arguments. In C++17, the compiler can also deduce the template arguments for class templates.

What are Variadic functions in C?

Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.


1 Answers

I don't think you can do this with variadic templates, but you can do it with the preprocessor.

I see two options. One would be to use Boost.Preprocessor:

// Definitions:
#define ARGUMENTS (T0)(T1)(T2)(T3)(Tx)

#define INSTANTIATE(maUnused, maTemplate, maType) \
  template class maTemplate<maType>;


// Usage:
BOOST_PP_SEQ_FOR_EACH(INSTANTIATE, Impl, ARGUMENTS)

BOOST_PP_SEQ_FOR_EACH(INSTANTIATE, Impl2, ARGUMENTS)

Another option would be to use the X macro trick:

x.hpp

X(T0)
X(T1)
X(T2)
X(T3)
X(Tx)

#undef X

using_file.cpp

#define X(maType) template class Impl<maType>;
#include "x.hpp"

#define X(maType) template class Impl2<maType>;
#include "x.hpp"
like image 90
Angew is no longer proud of SO Avatar answered Sep 23 '22 17:09

Angew is no longer proud of SO