Samaursa
Samaursa

Reputation: 17197

Prevent all instantiations of a template class - including supported types

If I have a template class MyClass<T> and if I explicitly instantiate for int and float (in a cpp file) then I can use extern template class MyClass<int> and extern template class MyClass<float> to prevent any compilation unit encountering this class from instantiating it for int and float unnecessarily. Of course, for any other type, the class will still get instantiated.

Now I have a class MyClass2<T> which only works with int, float, char, double, short and their unsigned variants where applicable. Since I know all the types beforehand, the definitions of all the methods in this class are in the cpp file. This is also where I explicitly instantiate MyClass2<T> for all the above mentioned types. In the header, I have static_assert preventing the user from creating MyClass2<T> with an unsupported type.

Is there any way to completely prevent MyClass2<T> from instantiating (e.g. extern template class MyClass2; although I know that doesn't work) for all types including supported types? Like a catch all for extern template? I want to avoid typing out extern template class MyClass2<int> for all the supported types.

Considering I have already explicitly instantiated the class for those types, it seems not only redundant but for big projects (like the one I am working on) yet another few lines that I need to maintain each time a new type is added.

Upvotes: 1

Views: 463

Answers (3)

T.C.
T.C.

Reputation: 137310

This honestly sounds like the job for a macro:

// explicit_instantiations.h
#ifndef PERFORM_INSTANTIANTION
#define EXTERNALLY_INSTANTIATED extern
#else
#define EXTERNALLY_INSTANTIATED
#endif

EXTERNALLY_INSTANTIATED template class MyClass<int>;
EXTERNALLY_INSTANTIATED template class MyClass<float>;
// etc.

// header
#include "explicit_instantiations.h"

// cpp file
#define PERFORM_INSTANTIATION
#include "explicit_instantiations.h"

Upvotes: 1

P0W
P0W

Reputation: 47784

You can use SFINAE something like following

template<typename T>
using value_type =  typename std::enable_if<
                    std::is_same<float, T>::value ||
                    std::is_same<double, T>::value
                    //...other supported types goes here
                   >::type  ;



template<class T, class Enable = void>
class  MyClass2 ;

template<class T>
class MyClass2<T, value_type<T> > 
{
};

 MyClass2<float> t;
 MyClass2<int> t1; // Error !

See Here

Upvotes: 2

user2249683
user2249683

Reputation:

What about:

template <typename T>
struct Base {};

template <typename T> 
struct Supported;

template <> 
struct Supported<int> : public Base<int>
{};

Upvotes: 0

Related Questions