如果不存在特定的自由函数,从重载集中删除模板函数的规范方法是什么。所以我有一个功能
template <typename T> void foo( T t )
{
// Do stuff
}
如果一个自由函数采用类型为T的参数,我想从重载集中删除它,比如说
bar( T )
不存在。
如果自由函数确实存在,那么如何从重载中删除一个函数。如果功能栏确实存在,请删除上面的函数foo?
答案 0 :(得分:4)
像这样的简单表达式可以很容易地与decltype
一起使用SFINAE:
template <typename T>
auto foo( T t ) -> decltype(bar(t), void())
{
// Do stuff
}
答案 1 :(得分:2)
Date()
这为我们提供了一个特征namespace details {
template<template<class...>class Z, class, class...Ts>
struct can_apply:std::false_type{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...>:std::true_type{};
};
template<template<class...>class Z, class...Ts>
using can_apply = details::can_apply<Z, void, Ts...>;
template<class T>
using bar_r = decltype( bar( std::declval<T>() ) );
template<class T>
using can_bar = can_apply<bar_r, T>;
can_bar
iff true
是一个有效的表达式。
bar(t)
的优点是SFINAE不会弄乱template<class T>
std::enable_if_t< can_bar<T>{}, int> =0
>
void foo( T t ) {}
函数的明显签名。反之亦然:
foo
这种技术的另一个优点。
请注意,如果您在左值上下文中调用它而不是转发它,则可能需要template<class T>
std::enable_if_t< !can_bar<T>{}, int> =0
>
void foo( T t ) {}
而不是can_bar<T&>
。
上面的一些内容超出了C ++ 11。
它使用T
的C ++ 14功能。在C ++ 11中将enable_if_t
替换为enable_if_t<blah>
,或者编写自己的typename enable_if<blah>::type
。
它还使用enable_if_t
的C ++ 14功能。
std::void_t
用C ++ 11编写。
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t = typename voider<Ts...>::type;
,跟C ++ 20一样,与上面的is_detected
类似。
答案 2 :(得分:1)
template <typename T, typename = decltype( bar( std::declval<T>() ), void() ) >
void foo( T t )
{
// Do stuff
}