Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disallow a specific function template instantiation

Tags:

c++

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.

like image 357
edA-qa mort-ora-y Avatar asked Apr 22 '11 10:04

edA-qa mort-ora-y


People also ask

How do you instantiate a function template?

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.

Are functions instantiated?

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.

What is instantiation of a template?

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.


1 Answers

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.

like image 157
wheaties Avatar answered Sep 29 '22 06:09

wheaties