Saturday, May 9, 2009

Is it possible to disallow certain template types using template specialization in C++?

How can I restrict a programmer to instantiating a template class with only certain variable types in C++? A simple example would be if I only want to allow the programmer to use a template class with either floats or doubles. Or perhaps allow all types except int.





Is there a way to do this so that I do not need to specify separate template specializations for both floats and doubles? How can I provide a single specialized template for both float and double instantiations?

Is it possible to disallow certain template types using template specialization in C++?
Yes, you can. By using a helper template class, you can create a compiler error.





You can find the idea here:


http://www.dbforums.com/showthread.php?t...





Depending on how you define the unspecialized helper template, you can either default to allow and specialize to block certain type or default to block and specialize to allow certain types. If you default to block and specialize to allow, then it is possible that a user of your template figures out your design and does the specialization to allow.





In the case where you default to block:


template %26lt;class T%26gt; class AllowInstantiation { AllowInstantiation(){} };





This template creates an empty class with a private constructor. In your main template create:





template%26lt;class T%26gt; class MyRealClass


{


// yadda yadda yadda


AllowInstantiation%26lt;T%26gt; m_allowTemplate;


};





For any class that does not have an specialization of AllowInstantiation, MyRealClass cannot be instantiated because of AllowInstantiation's private constructor.





To allow a type, specialize AllowInstantiation. For example to allow float:


template %26lt;%26gt; class AllowInstantiation%26lt;float%26gt; {};


The default constructor for the empty class defaults to public and so it can be instantiated.





To do the reverse, i.e. allow most types and block a few


template %26lt;class T%26gt; class AllowInstantiation {};


Unspecialized template allows default constructor.





template %26lt;%26gt; class AllowInstantiation%26lt;int%26gt; { AllowInstantiation(){}};





Now int is blocked because of private constructor.


No comments:

Post a Comment