当某个表达式是un_defined时,是否可以启用函数模板(例如,x
类型的t
是_not流到std::cout
)。有点像
template<typename t>
auto f(const t &x)
-> typename enable_if_undefined<decltype(std::cout << x)>::type;
使用SFINAE,我只看到如何启用表达式的定义,而不是如何做,如果表达式是未定义的。
发布于 2015-05-05 07:21:49
您需要一个可以反向提供布尔值的助手:
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;
发布于 2015-05-05 11:32:37
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...>>;
是元编程样板。
然后,实际的用例特定代码是非常干净的。首先,一个简单的decltype
别名:
template<class X>
using cout_result = decltype( std::cout << std::declval<X>() );
然后我们对它进行测试:
template<class X>
using can_cout_stream = test_apply< cout_result, X >;
这里的目标是将元编程样板与实际使用分离开来。
template<class T>
std::enable_if_t<!can_cout_stream<const T&>{}>
f(const T& x)
我慷慨地使用C++14特性使事物变得更干净。如果您的编译器没有它们,它们都可以很容易地在C++11中实现。
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;
应该包括在内。
https://stackoverflow.com/questions/30056790
复制