std::result_of - cppreference.com

##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# std::result_of

From cppreference.com
< cpp‎ | types

Defined in header `<type_traits>` |  |
template< class > class result_of; //not defined | (1) | (since C++11)
template< class F, class... ArgTypes > class result_of<F(ArgTypes...)>; | (2) | (since C++11)

Deduces the return type of a function call expression at compile time.

`F` must be a callable type, reference to function, or reference to callable type. Invoking `F` with `ArgTypes...` must be a well-formed expression | (since C++11)
`F` and all types in `ArgTypes` can be any complete type, array of unknown bound, or (cv-qualified) void | (since C++14)

### [edit] Member types

Member type | Definition
`type` | the return type of the `Callable` type `F` if invoked with the arguments `ArgTypes...`. Only defined if F can be called with the arguments ArgTypes... in unevaluated context. (since C++14)

### [edit] Helper types

template< class T > using result_of_t = typename result_of<T>::type; |  | (since C++14)

### [edit] Possible implementation

    template <class> struct result_of;

    namespace detail {
    template <class F, class... Args>
    inline auto INVOKE(F&& f, Args&&... args) ->
        decltype(forward<F>(f)(forward<Args>(args)...)) {
          return forward<F>(f)(forward<Args>(args)...);
    }

    template <class Base, class T, class Derived>
    inline auto INVOKE(T Base::*&& pmd, Derived&& ref) ->
        decltype(forward<Derived>(ref).*forward<T Base::*>(pmd)) {
          return forward<Derived>(ref).*forward<T Base::*>(pmd);
    }

    template <class PMD, class Pointer>
    inline auto INVOKE(PMD&& pmd, Pointer&& ptr) ->
        decltype((*forward<Pointer>(ptr)).*forward<PMD>(pmd)) {
          return (*forward<Pointer>(ptr)).*forward<PMD>(pmd);
    }

    template <class Base, class T, class Derived, class... Args>
    inline auto INVOKE(T Base::*&& pmf, Derived&& ref, Args&&... args) ->
        decltype((forward<Derived>(ref).*forward<T Base::*>(pmf))(forward<Args>(args)...)) {
          return (forward<Derived>(ref).*forward<T Base::*>(pmf))(forward<Args>(args)...);
    }

    template <class PMF, class Pointer, class... Args>
    inline auto INVOKE(PMF&& pmf, Pointer&& ptr, Args&&... args) ->
        decltype(((*forward<Pointer>(ptr)).*forward<PMF>(pmf))(forward<Args>(args)...)) {
          return ((*forward<Pointer>(ptr)).*forward<PMF>(pmf))(forward<Args>(args)...);
    }
    } // namespace detail

    // C++11 implementation:
    template <class F, class... ArgTypes>
    struct result_of<F(ArgTypes...)> {
        using type = decltype(detail::INVOKE(
            declval<F>(), declval<ArgTypes>()...
        ));
    };

    // C++14 implementation:
    namespace detail {
    template <class F, class... ArgTypes>
    struct invokeable {
        template <typename U = F>
        static auto test(int) -> decltype(INVOKE(
            declval<U>(), declval<ArgTypes>()...
        ), void(), true_type());

        static auto test(...) -> false_type;

        static constexpr bool value = decltype(test(0))::value;
    };

    template <bool B, class F, class... ArgTypes>
    struct _result_of {
        using type = decltype(INVOKE(
            declval<F>(), declval<ArgTypes>()...
        ));
    };

    template <class F, class... ArgTypes>
    struct _result_of<false, F, ArgTypes...> { };
    } // namespace detail

    template <class F, class... ArgTypes>
    struct result_of<F(ArgTypes...)> :
        detail::_result_of<detail::invokeable<F, ArgTypes...>::value, F, ArgTypes...> { };

### [edit] Notes

As formulated in C++11, `std::result_of` would fail to compile when F(ArgTypes...) is ill-formed (e.g. when F is not a callable type at all). C++14 changes that to a SFINAE (when F is not callable, `std::result_of<F(Args...)>` simply doesn't have the `type` member).

### [edit] Examples

`std::result_of` can be used to determine the result of invoking a functor, in particular if the result type is different for different sets of arguments:

Run this code

    #include <type_traits>

    struct S {
        double operator()(char, int&);
        float operator()(int);
    };

    struct C {
        double Func(char, int&);
    };

    int main()
    {
        // the result of invoking S with char and int& arguments is double
        std::result_of<S(char, int&)>::type f = 3.14; // f has type double
        static_assert(std::is_same<decltype(f), double>::value, "");

        // the result of invoking S with int argument is float
        std::result_of<S(int)>::type d = 3.14; // f has type float
        static_assert(std::is_same<decltype(d), float>::value, "");

        // result_of can be used with a pointer to member function as follows
        std::result_of<decltype(&C::Func)(C, char, int&)>::type g = 3.14;
        static_assert(std::is_same<decltype(g), double>::value, "");
    }

This program takes advantage of the C++14 changes to overload two functions on the "callability" of a template parameter:

Run this code

    #include <type_traits>
    #include <iostream>

    template<class T>
    typename std::result_of<T(int)>::type
    f(T& t)
    {
        std::cout << "overload of f for callable T\n";
        return t(0);
    }

    template<class T, class U>
    int f(U u)
    {
        std::cout << "overload of f for non-callable T\n";
        return u;
    }

    struct S {};

    int main() {
      f<S>(1); // fails to compile in C++11, calls the non-callable overload in C++14
    }

Output:

    overload of f for non-callable T

### [edit] See also

declval (C++11) | obtains the type of expression in unevaluated context (function template) [edit]

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/types/result_of&oldid=72239"