模板的部分特化

6

请考虑:

template <typename Function, typename ...Args>
auto wrapper(Function&& f, Args&&... args) -> decltype(f(args...)) {
//...
}

有没有一种方法可以部分专门化上面的模板,以涵盖所有decltype(f(args...))是指针的情况?

编辑:
我认为可以通过一个模板助手类来实现,该类以decltype(f(args...))作为模板参数,并专门化助手类。如果您知道更好的解决方案,请告诉我。

2个回答

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

正如您所看到的,返回类型不是模板参数或参数的一部分,因此您无法进行重载或专门化。在助手上进行调度是您的最佳选择。

#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); }

虽然通过右值引用获取函数并且在原始示例中省略了转发,但这对我来说似乎有点奇怪。

另一个可能的解决方案是使用模板默认参数并对其进行重载。但这在参数列表中不起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接