Search code examples
c++c++11templates

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?


Solution

  • 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.