写入get_last
,提取参数包的最后一个元素。
调用它f
。打电话f
。
举个例子,
template<typename T0>
auto get_last( T0&& t0 )->decltype(std::forward<T0>(t0))
{
return std::forward<T0>(t0);
}
template<typename T0, typename... Ts>
auto get_last( T0&& t0, Ts&&... ts )->decltype(get_last(std::forward<Ts>(ts)...))
{
return get_last(std::forward<Ts>(ts)...);
}
如果您不关心重载解决方案,只需get_last
像函子一样调用和对待它可能就足够了:
template <typename...Args>
void call(const char *name, Args...&& args)
{
auto&& f = get_last(std::forward<Args>(args)...);
f(3);
}
下一步是做一些 SFINAEenable_if
魔术,以便在call
最后没有传递有效函子的情况下使失败匹配:但是,这可能是矫枉过正。
为了检测是否f(3)
会起作用,一个简单的特征类:
// trivial traits class:
template<typename T>
struct is_type:std::true_type {};
template<typename Functor, typename=void>
struct can_be_called_with_3:std::false_type {}
template<typename Functor>
struct can_be_called_with_3<Functor,
typename std::enable_if<
std::is_type< decltype(
std::declval<Functor>(3)
) >::value
>::type
>:std::true_type {}
这很愚蠢。如果您对传入类型的要求更复杂(例如,您希望使用参数调用它),则必须使用更高级的特征类。
然后你增加call
:
template <typename...Args>
auto call(const char *name, Args...&& args)
-> typename std::enable_if<
can_be_called_with_3< decltype( get_last(std::forward<Args>(args)... ) ) >::value
>::type
{ /* body unchanged */ }
这很钝。