vendredi 28 août 2015

Proper way of template specializations for different types

As looking into libraries, stackoverflow questions and articles on the web, it turns out there are two main way in C++11 to create template specializations (partial if needed) of the same functionality for different types:

function template with SFINAE return type

namespace detail
{    
    template <class T>
    typename std::enable_if<std::is_integral<T>::value, T>::type
    compute_thing(T n)
    {
    return T(0);
    }

    template <class T>
    typename std::enable_if<std::is_floating_point<T>::value, T>::type
    compute_thing(T n)
    {
    return T(1);
    }
}

template <class T>
T compute_thing(T n)
{
    return detail::compute_thing<T>(n);
}

struct/class template with SFINAE partial specialization

namespace detail
{    
    template <class T, class Enable = void>
    struct compute_thing;

    template <class T>
    struct compute thing<T, typename std::enable_if<std::is_integral<T>::value, T>::type>
    {
        static T call(T x)
        {
            return T(0);
        }
    }

    template <class T>
    struct compute thing<T, typename std::enable_if<std::is_floating_point<T>::value, T>::type>
    {
        static T call(T x)
        {
            return T(1);
        }
    }     
}

template <class T>
T compute_thing(T n)
{
    return detail::compute_thing<T>::call(n);
}

However it's not clear:

  • Which style should be preferred and why?
  • What are the advantages/disadvantages in terms of reusability, versatility, compile-time and runtime performance?

Aucun commentaire:

Enregistrer un commentaire