模板的部分特化

时间:2012-06-16 12:03:13

标签: c++ templates

考虑:

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

对于decltype(f(args...))是指针的所有情况,有没有办法对上述模板进行部分专门化?

修改
我认为可以使用模板助手类来完成,该类以decltype(f(args...))作为模板参数,并专门化助手类。如果你知道更好的解决方案,请告诉我。

2 个答案:

答案 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); }

通过右值引用来获取函数似乎有点奇怪,你也省略了原始示例中的转发。

另一种可能的解决方案可能是模板默认参数和重载。但这对参数列表不起作用。