Search code examples
c++templatesc++11drysfinae

How correctly to remove code repetition in template function


I have code like this ("spaceship"-like operator).

template <class T>
int comparator(const T &a, const T &b){
    if (a < b){
        return -1;
    }else if (a > b){
        return +1;
    }

    return 0;
}

inline int comparator(const char *a, const char *b){
    return strcmp(a, b); // I never tried this, included just to get the idea
}

inline int comparator(char const a, char const b){
    return a - b;
}

inline int comparator(int const a, int const b){
    return a - b;
}

How can I easily remove repetition for several signed types (char, short, int, long etc). I tried with SFINAE, but result was not very encouraging.


Solution

  • You can mix together overloading, tag dispatching and templates, as in the following example:

    #include<type_traits>
    #include<utility>
    #include<iostream>
    
    template <class T>
    int comparator_(char, const T &a, const T &b){
        std::cout << "catch all" << std::endl;
        return (a<b)?-1:((a>b)?1:0);
    }
    
    template<typename T>
    std::enable_if_t<std::is_same<T,int>::value or std::is_same<T,char>::value, int>
    comparator_(int, T const a, T const b){
        std::cout << "char or int" << std::endl;
        return a - b;
    }
    
    template<typename... A>
    int comparator(A&&... args) {
        return comparator_(0, std::forward<A>(args)...);
    }
    
    int main() {
        comparator(42,0);
        comparator('c', 'g');
        comparator(42u, 0u);
    }