Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template specialization all types except one

I need a method(C++ 11) that is called for all types except one.

template<typename T>
void method(T& value)
{
...
}

template<>
void method(std::string& value)
{
...
}

Is it possible to do something like this? If not, is there other alternatives than using typeid at runtime?

like image 589
Raluca Avatar asked Oct 24 '25 21:10

Raluca


2 Answers

there are several ways to do this, so you can use most convenient one:

// way 1
template<typename T, 
         typename std::enable_if<!std::is_same<T,std::string>::value>::type* = nullptr>
// way 2
void method(T& value)
{
    static_assert(!std::is_same<T,std::string>::value,"std::string is not accepted");
    ...
}

// way 3
template <>
void method<std::string>(std::string&) = delete; 

As for me, I find 3 to be the most convenient one for filtering out specific type, and 1 for filtering out some subset of types

like image 174
Andrei R. Avatar answered Oct 26 '25 13:10

Andrei R.


You do not need template specialization. And neither SFINAE (enable_if). When you get caught up in template functions it's easy to forget that functions can overload. Just create a non-templated overload and that will be preferred when passing an argument of that exact type (a better solution is presented in the linked article):

template<typename T>
void method(T& value)
{
  // ...
}

void method(std::string& value)
{
  // ...
}

I strongly recommend reading this article Why Not Specialize Function Templates? by Herb Sutter.

Moral #1: If you want to customize a function base template and want that customization to participate in overload resolution (or, to always be used in the case of exact match), make it a plain old function, not a specialization. And, if you do provide overloads, avoid also providing specializations.

But you fall in the Moral #2:

But what if you're the one who's writing, not just using, a function template? Can you do better and avoid this (and other) problem(s) up front, for yourself and for your users? Indeed you can:

Moral #2: If you're writing a function base template, prefer to write it as a single function template that should never be specialized or overloaded, and then implement the function template entirely as a simple handoff to a class template containing a static function with the same signature. Everyone can specialize that -- both fully and partially, and without affecting the results of overload resolution.

The whole explanation is in the article.

like image 35
bolov Avatar answered Oct 26 '25 12:10

bolov