考虑:
template <typename Function, typename ...Args>
auto wrapper(Function&& f, Args&&... args) -> decltype(f(args...)) {
//...
}
对于decltype(f(args...))
是指针的所有情况,有没有办法对上述模板进行部分专门化?
修改:
我认为可以使用模板助手类来完成,该类以decltype(f(args...))
作为模板参数,并专门化助手类。如果你知道更好的解决方案,请告诉我。
答案 0 :(得分:3)
基于SFINAE的解决方案:
#include <type_traits>
template<
typename Functor
, typename... Args
, typename Result = decltype(std::declval<Functor&>()(std::declval<Args>()...))
, typename std::enable_if<
std::is_pointer<Result>::value
, int
>::type = 0
>
Result wrapper(Functor&& functor, Args&&... args)
{ /* ... */ }
template<
typename Functor
, typename... Args
, typename Result = decltype(std::declval<Functor&>()(std::declval<Args>()...))
, typename std::enable_if<
!std::is_pointer<Result>::value
, int
>::type = 0
>
Result wrapper(Functor&& functor, Args&&... args)
{ /* ... */ }
您可以根据需要调整测试(此处为std::is_pointer<Result>
)。
答案 1 :(得分:1)
如您所见,返回类型不是模板参数或参数的一部分,因此您不能重载也不能专门化。派遣助手是您最好的选择。
#include <type_traits>
template<typename Func, typename... Args>
void func_impl(Func&& f, Args&&... args, std::true_type)
-> decltype(func_impl(std::forward<Args>(args)...))
{ }
template<typename Func, typename... Args>
void func_impl(Func&& f, Args&&... args, std::false_type)
-> decltype(func_impl(std::forward<Args>(args)...))
{ }
template<typename Func, typename... Args>
auto func(Func&& f, Args&&... args)
-> decltype(func_impl(std::forward<Func>(f), std::forward<Args>(args)...))
{ return func_impl(std::forward<Func>(f), std::forward<Args>(args)...,
std::is_pointer<decltype(f(std::forward<Args>(args)...))>::type); }
通过右值引用来获取函数似乎有点奇怪,你也省略了原始示例中的转发。
另一种可能的解决方案可能是模板默认参数和重载。但这对参数列表不起作用。