Thursday 1 May 2014

Using function template default parameters to elegantly create SFINAE overloads

Having read Remastered enable_if, some implementation was left as an exercise for the reader.

The article explains how to make use of function template default parameters to elegantly create SFINAE overloads.

Below is my implementation.

#include <iostream>
#include <type_traits>

// true iff all conditions ::values are true
template <typename Head, typename... Tail>
struct all
{
    static constexpr bool value = Head::value && all<Tail...>::value;
};
template <typename Head>
struct all<Head>
{
    static constexpr bool value = Head::value;
};
//---------------------------------

// scoped enum to allow for differentiation between enable/disable
namespace detail { enum class enabler {}; }

template <typename... Condition>
using enable_if_t = typename std::enable_if<all<Condition...>::value, detail::enabler>::type;

template <typename... Condition>
using disable_if_t = typename std::enable_if<!all<Condition...>::value>::type;

//---------------------------------

// example function showing SFINAE overloads
template <typename T,
          enable_if_t< std::is_arithmetic<T>
                     , std::is_integral<T>
                     >...>
T twice(T t)
{
    return 2*t;
}
template <typename T,
          disable_if_t< std::is_arithmetic<T>
                      , std::is_integral<T>
                      >...>
T twice(T t)
{
    return t + t;
}
//---------------------------------

int main()
{
    std::cout << twice(5) << std::endl;
    std::cout << twice(std::string("Hello world")) << std::endl;
    return 0;
}

Read more here

No comments:

Post a Comment