Suki wrote:[color=blue]
> Hi,
> I'm writing a templated class, and i dont want to use the class
> otherthan for some predetermined types, say, int, double etc.
>
> This class has no meaning for typenames other than those few.
>
> =========================
> template <class T>
> myClass {....} ;
>
> myClass<int> intClass ;
> myClass<float> floatClass ;
> myClass<char> charClass ;
> =========================
>
> The compiler should not complain for the first 2 instantiations, but
> should bail out at the 3rd instantiation (charClass). Is there any way
> i
> can achieve this, using standard c++ or boost.
>
> I've tried explicit template instantiation, (by passing a flag to my
> compiler), but in that case, i've to do that for every class
>
> suppose i try to invoke
> std::vector <someOtherClass> someVector;
>
> I've to instantiate this also explicitly. (which is a problem for me,
> because, I use a lot of standard library, and its a pain for me to
> instantiate every time.
>
> Also, if i do the above, i can always instantiate myClass also like
> this.
>
> template class myClass <someOtherClass> ;
>
> and which i want to avoid this..
>
> to summarize my question,
> is there any way i can restrict the compiler to accept only few type
> names for my templated class (i.e., using standard c++ or boost)[/color]
First, I would not recommend turning off implicit template
instantiation. The aim here is really not to selectively instantiate -
but to selectively specialize - the template. If the class template is
specialized only for the approved types then only those types will be
able to instantiate the template successfully.
Along these lines, the simplistic solution would be to specialize the
template for each approved type:
template <class T>
class MyClass; // not defined
template <>
class MyClass<int>
{
...
};
template <>
class MyClass<float>
{
...
};
While this technique may be manageable for a few classes and a simple
template, the duplication of the template across each type makes
maintainence inconvenient and error-prone.
Fortunately, C++ allows templates and inheritance to be used together.
And it is this combination that leads to a much more maintainable
solution.
First, declare a base class template that implements the complete
template but whose constructor is protected:
template <class T>
class BaseClass
{
protected:
BaseClass();
public:
... // implement entire template here
};
Next declare (but do not define) the MyClass class template:
template <class T>
class MyClass;
Finally, specialize MyClass for each approved type, as above. Only this
time, the specialization will inherit from the BaseClass template to
obtain the the desired implementation for its type:
template <>
MyClass<int> : public BaseClass<int>
{
public:
MyClass();
...
};
This mechanism prevents anyone from inadvertently instantiating a
MyClass for a non-specialized type and from directly instantiating a
BaseClass for any type.
But one has to wonder whether discouraging the instantiation of
MyClass<char> is really worth going to such lengths. After all, if
MyClass<char> is a plausible specialization, than it probably should be
allowed. On the other hand, if MyClass<char> makes no sense, then
simply relying on the fact that there would never be a good reason to
instantiate MyClass<char> should be a sufficient deterrent. Lastly, it
is always possible to document the template class and list its
supported types. And then the matter would simply rely on each client's
own good judgment.
Greg
[ See
http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]