Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional explicit template instantiation

Other than the preprocessor, how can I conditionally enable/disable explicit template instantiations?

Consider:

template <typename T> struct TheTemplate{ /* blah */ };

template struct TheTemplate<Type1>;
template struct TheTemplate<Type2>;
template struct TheTemplate<Type3>;
template struct TheTemplate<Type4>;

Under some compilation conditions, Type3 is the same as Type1 and Type4 is the same as Type2. When this happens, I get an error. I'd like to detect that the types are the same and not instantiate on Type3 and Type4 as in

// this does not work
template struct TheTemplate<Type1>;
template struct TheTemplate<Type2>;
template struct TheTemplate<enable_if<!is_same<Type1, Type3>::value, Type3>::type>;
template struct TheTemplate<enable_if<!is_same<Type2, Type4>::value, Type4>::type>;

I've diverted myself trying enable_if and SFINAE (and I believe I know why they fail), but only the preprocessor has worked (ugh). I'm thinking about putting the types in a tuple or variadic, removing duplicates, and then use the remainder for instantiation.

Is there a way to conditionally enable/disable explicit template instantiation based on template argument types?

like image 756
walrii Avatar asked Dec 18 '12 03:12

walrii


People also ask

How do I force a template instantiation?

To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>(float original); Template arguments may be omitted when the compiler can infer them.

What is the instantiation of the class template?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation.

Is it necessary to instantiate a template?

Class template instantiationIn order for any code to appear, a template must be instantiated: the template arguments must be provided so that the compiler can generate an actual class (or function, from a function template).

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.


1 Answers

template <typename T> struct TheTemplate{ /* blah */ };

template<int> struct dummy { };

template struct TheTemplate<Type1>;
template struct TheTemplate<Type2>;
template struct TheTemplate<conditional<is_same<Type1, Type3>::value, dummy<3>, Type3>::type>;
template struct TheTemplate<conditional<is_same<Type2, Type4>::value, dummy<4>, Type4>::type>;

This still produces four explicit instantiations, but they won't be duplicates in the case where Type3 is the same as Type1 (unless Type1 is dummy<3>!)

like image 114
Jonathan Wakely Avatar answered Sep 23 '22 11:09

Jonathan Wakely