6

考虑:

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

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

编辑
我认为它可以用一个模板帮助类来完成,它decltype(f(args...))作为模板参数,并专门化帮助类。如果您知道更好的解决方案,请告诉我。

4

2 回答 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>)。

于 2012-06-16T13:06:19.250 回答
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); }

不过,通过右值引用来获取函数对我来说似乎有点奇怪,而且您在原始示例中也省略了转发。

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

于 2012-06-16T12:46:01.527 回答