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