Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial specialization of a template

Tags:

c++

templates

Consider:

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

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

EDIT:
I think it can be done with an template helper class which takes decltype(f(args...)) as template argument, and specialize the helper class. If you know better solutions let me know.

like image 576
Martin Avatar asked Jun 16 '12 12:06

Martin


People also ask

What is the difference between partial specialization and template specialization?

An explicit specialization only has a template argument list. A partial specialization has both a template argument list and a template parameter list. The compiler uses the partial specialization if its template argument list matches a subset of the template arguments of a template instantiation.

What is a template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

What is explicit Specialisation?

Explicit (full) specializationAllows customizing the template code for a given set of template arguments.

How many types of template are there?

There are three kinds of templates: function templates, class templates and, since C++14, variable templates.


1 Answers

An 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.

like image 56
Luc Danton Avatar answered Oct 12 '22 22:10

Luc Danton