Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent implicit template instantiations for a specific template?

I'd like to prevent all implicit template instantiations for a specific templated class in order to prevent it from being instantiated into every translation unit.

It looks like my options are:

  1. Use -fno-implicit-templates on gcc's command line. This suppresses all implicit template instantiations, and is not what I want. I only want to prevent it for a single template.
  2. Use C++11 "extern template". But this only suppresses specific explicit instantiations. I don't want to type out an "extern template" line for every potential template parameter list this template might be instantiated with.

So I need something in-between. It would be nice to have:

 extern template class Foo; // suppress all implicit instantiations of Foo

(Note the lack of template parameter(s).) Any ideas?

like image 535
Aaron Graham Avatar asked May 27 '15 03:05

Aaron Graham


People also ask

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

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.

Under what circumstances will C++ instantiate a generic function implicitly?

Unless a template specialization has been explicitly instantiated or explicitly specialized, the compiler will generate a specialization for the template only when it needs the definition. This is called implicit instantiation.


2 Answers

you can use std::enable_if which does exactly this with the combination of std::is_same :

template <class T , typename = std::enable_if <!std::is_same<T,Foo>::value,T>::type >
class MyClass{
//...
};

now myClass won't be compiled for Foo type.

like image 130
David Haim Avatar answered Sep 30 '22 13:09

David Haim


I would say that the answer to your question is using C++ new type traits to assert the instantiations in your constructor:

static_assert(std::is_same<TInstantiation, [your-predefined-type]> || std::is_same<TInstantiation, [your-predefined-type2]> /*And so on...*/, "Classname can not be instantiated using this type!");

It's all guaranteed to resolve at compile time :)

like image 37
paladin324 Avatar answered Sep 30 '22 13:09

paladin324