13

I need to write a templated function, that behaves differently depending on the class of its parameter:

template<class ContainerType>
bool myFunc(ContainerType in){
//do some stuff
}

template<class NotAContainerType>
bool myFunc(NotAContainerType in){
//do something else
}

I am restricted to C++11, so static_if is off the table. Also, the classes of ContainerType and NotAContainerType are really large and might change in the future, so just adding a few exceptions by hand as a template specialization is not sensible either.

I am aware of the std::enable_if workaround, but how do I use it, if I need to apply it to two mutually distinct sets of classes?

Giacomo Alzetta
  • 2,431
  • 6
  • 17
Jonn Dove
  • 477
  • 2
  • 11
  • 2
    How do you distinct those types of classes? Without that code, we can't help you much. – Jaa-c Jul 25 '18 at 08:33
  • 1
    `std::enable_if`is exactly what you are looking for - so just define how you distinguish a "container" type from others. – scrutari Jul 25 '18 at 08:34
  • @Jaa-c, I distinguish them just as their names suggest: ContainerType for std::containers (e.g. they have an iterator ), and NotAConatinerType for anything else – Jonn Dove Jul 25 '18 at 08:46

1 Answers1

20

Create a traits for your concept Container, then, you might use SFINAE

template <typename T>
typename std::enable_if<is_container<T>::value, bool>::type
myFunc(T in){
    //do some stuff
}

template <typename T>
typename std::enable_if<!is_container<T>::value, bool>::type
myFunc(T in){
    //do some stuff
}

or tag dispatching

namespace details
{

    template <typename T>
    bool myFunc(T in, std::true_type){
        //do some stuff
    }

    template <typename T>
    bool myFunc(T in, std::false_type){
        //do some stuff
    }

}


template <typename T>
bool myFunc(T in){
    return details::myFunc(in, is_container<T>{});
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Jarod42
  • 203,559
  • 14
  • 181
  • 302