I would like to define a template function but disallow instantiation with a particular type. Note that in general all types are allowed and the generic template works, I just want to disallow using a few specific types.
For example, in the code below I wish to prevent using double
with the template. This doesn't actually prevent the instantiation, but just causes a linker error by not having the function defined.
template<typename T>
T convert( char const * in )
{ return T(); }
//this way creates a linker error
template<>
double convert<double>( char const * in );
int main()
{
char const * str = "1234";
int a = convert<int>( str );
double b = convert<double>( str );
}
The code is just a demonstration, obviously the convert function must do something more.
Question: In the above code how can I produce a compiler error when trying to use the convert<double>
instantiation?
The closest related question I can find is How to intentionally cause a compile-time error on template instantiation It deals with a class, not a function.
The reason I need to do this is because the types I wish to block will actually compile and do something with the generic version. That's however not supposed to be part of the contract of the function and may not be supported on all platforms/compilers and in future versions. Thus I'd like to prevent using it at all.
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.
When a function template is first called for each type, the compiler creates an instantiation. Each instantiation is a version of the templated function specialized for the type. This instantiation will be called every time the function is used for the type.
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. The definition created from a template instantiation to handle a specific set of template arguments is called a specialization.
I would use a static assert within your function call to create the proper failure during function instantiation:
template<typename T>
class is_double{ static const int value = false; }
template<>
class is_double<double>{ static const int value = true; }
template<typename T>
T convert( const char *argument ){
BOOST_STATIC_ASSERT( !is_double<T>::value );
//rest of code
}
And that should work within a function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With