Include C ++ function template whenever expression is undefined
Is it possible to activate the function template whenever any expression is undefined (for example, the x
type t
does not support stream before std::cout
). Something like
template<typename t>
auto f(const t &x)
-> typename enable_if_undefined<decltype(std::cout << x)>::type;
Using SFINAE, I only see how to include if the expression is defined, but not how to do it if the expression is undefined.
source to share
You need a helper that provides a boolean value that you can change:
template<typename, typename=void>
struct has_cout
: std::false_type {};
template<typename T>
struct has_cout<T, decltype(std::cout << std::declval<T>(),void())>
: std::true_type {};
template<typename T>
auto f(const T& x)
-> typename std::enable_if<!has_cout<T>::value>::type;
source to share
template<class...>struct types{using type=types;};
namespace details {
template<template<class...>class Z, class types, class=void>
struct test_apply:std::false_type{};
template<template<class...>class Z, class...Ts>
struct test_apply<Z,types<Ts...>,std::void_t<Z<Ts...>>>:
std::true_type
{};
};
template<template<class...>class Z, class...Ts>
using test_apply=details::test_apply<Z,types<Ts...>>;
is a metaprogramming template.
Then the actual code of the specific use is really clean. First, a simple alias decltype
:
template<class X>
using cout_result = decltype( std::cout << std::declval<X>() );
and then apply a test to it:
template<class X>
using can_cout_stream = test_apply< cout_result, X >;
The goal is to separate the metaprogramming pattern from actual use.
template<class T>
std::enable_if_t<!can_cout_stream<const T&>{}>
f(const T& x)
I am free to use the power of C ++ 14 to keep things clean. All of them can be easily implemented in C ++ 11 if your compiler doesn't have them.
template<bool b, class T=void>
using enable_if_t=typename std::enable_if<b,T>::type;
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t=typename voider<Ts...>::type;
should cover it.
source to share