Partial template specialization

Consider:

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

Is there a way to partially specialize the above pattern for all cases where decltype(f(args...)) is a pointer?

EDIT :
I think this can be done with the help of the template helper class, which takes decltype(f(args...)) as the template argument and specializes the helper class. If you know the best solutions, let me know.

+6
source share
2 answers

SFINAE based solution:

 #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) { /* ... */ } 

You can adapt the test (here std::is_pointer<Result> ) to your needs.

+3
source

As you can see, the return type is not a template argument or part of the arguments, so you cannot overload or specialize. Sending on assistant is your best option.

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

It seems strange to me that I take the function by rvalue reference, but you also omit the forwarding in your original example.

Another possible solution might be the template default argument and overloading. But this will not work well with the argument list.

+1
source

Source: https://habr.com/ru/post/918237/


All Articles