GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
std::result_of,std::invoke_result(3) C++ Standard Libary std::result_of,std::invoke_result(3)

std::result_of,std::invoke_result - std::result_of,std::invoke_result


Defined in header <type_traits>
template< class >


class result_of; // not defined (since C++11)
(1) (deprecated in C++17)
template< class F, class... ArgTypes > (removed in C++20)


class result_of<F(ArgTypes...)>;
template< class F, class... ArgTypes> (2) (since C++17)
class invoke_result;


Deduces the return type of an INVOKE expression at compile time.


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


The behavior of a program that adds specializations for any of the templates
described on this page is undefined.


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


template< class T > (since C++14)
using result_of_t = typename result_of<T>::type; (1) (deprecated in C++17)
(removed in C++20)
template< class F, class... ArgTypes>
using invoke_result_t = typename invoke_result<F, (2) (since C++17)
ArgTypes...>::type;


namespace detail {
template <class T>
struct is_reference_wrapper : std::false_type {};
template <class U>
struct is_reference_wrapper<std::reference_wrapper<U>> : std::true_type {};


template<class T>
struct invoke_impl {
template<class F, class... Args>
static auto call(F&& f, Args&&... args)
-> decltype(std::forward<F>(f)(std::forward<Args>(args)...));
};


template<class B, class MT>
struct invoke_impl<MT B::*> {
template<class T, class Td = typename std::decay<T>::type,
class = typename std::enable_if<std::is_base_of<B, Td>::value>::type
>
static auto get(T&& t) -> T&&;


template<class T, class Td = typename std::decay<T>::type,
class = typename std::enable_if<is_reference_wrapper<Td>::value>::type
>
static auto get(T&& t) -> decltype(t.get());


template<class T, class Td = typename std::decay<T>::type,
class = typename std::enable_if<!std::is_base_of<B, Td>::value>::type,
class = typename std::enable_if<!is_reference_wrapper<Td>::value>::type
>
static auto get(T&& t) -> decltype(*std::forward<T>(t));


template<class T, class... Args, class MT1,
class = typename std::enable_if<std::is_function<MT1>::value>::type
>
static auto call(MT1 B::*pmf, T&& t, Args&&... args)
-> decltype((invoke_impl::get(std::forward<T>(t)).*pmf)(std::forward<Args>(args)...));


template<class T>
static auto call(MT B::*pmd, T&& t)
-> decltype(invoke_impl::get(std::forward<T>(t)).*pmd);
};


template<class F, class... Args, class Fd = typename std::decay<F>::type>
auto INVOKE(F&& f, Args&&... args)
-> decltype(invoke_impl<Fd>::call(std::forward<F>(f), std::forward<Args>(args)...));


} // namespace detail


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


// Conforming C++14 implementation (is also a valid C++11 implementation):
namespace detail {
template <typename AlwaysVoid, typename, typename...>
struct invoke_result { };
template <typename F, typename...Args>
struct invoke_result<decltype(void(detail::INVOKE(std::declval<F>(), std::declval<Args>()...))),
F, Args...> {
using type = decltype(detail::INVOKE(std::declval<F>(), std::declval<Args>()...));
};
} // namespace detail


template <class> struct result_of;
template <class F, class... ArgTypes>
struct result_of<F(ArgTypes...)> : detail::invoke_result<void, F, ArgTypes...> {};


template <class F, class... ArgTypes>
struct invoke_result : detail::invoke_result<void, F, ArgTypes...> {};


As formulated in C++11, the behavior of std::result_of is undefined when
INVOKE(std::declval<F>(), std::declval<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(ArgTypes...)> simply doesn't have the type member).


The motivation behind std::result_of is to determine the result of invoking a
Callable, in particular if that result type is different for different sets of
arguments.


F(Args...) is a function type with Args... being the argument types and F being the
return type. As such, std::result_of suffers from several quirks that led to its
deprecation in favor of std::invoke_result in C++17:


* F cannot be a function type or an array type (but can be a reference to them);
* if any of the Args has type "array of T" or a function type T, it is
automatically adjusted to T*;
* neither F nor any of Args... can be an abstract class type;
* if any of Args... has a top-level cv-qualifier, it is discarded;
* none of Args... may be of type void.


To avoid these quirks, result_of is often used with reference types as F and
Args.... For example:


template<class F, class... Args>
std::result_of_t<F&&(Args&&...)> // instead of std::result_of_t<F(Args...)>, which is wrong
my_invoke(F&& f, Args&&... args) {
/* implementation */
}


Feature-test macro: __cpp_lib_result_of_sfinae

// Run this code


#include <type_traits>
#include <iostream>


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


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


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


// std::invoke_result uses different syntax (no parentheses)
std::invoke_result<S,char,int&>::type b = 3.14;
static_assert(std::is_same<decltype(b), double>::value, "");


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


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


f<C>(1); // may fail to compile in C++11; calls the non-callable overload in C++14
}


overload of f for non-callable T


invoke invokes any Callable object with given arguments
invoke_r and possibility to specify return type
(C++17) (since C++23)
(C++23) (function template)
is_invocable
is_invocable_r checks if a type can be invoked (as if by std::invoke) with
is_nothrow_invocable the given argument types
is_nothrow_invocable_r (class template)
(C++17)
declval obtains a reference to its argument for use in unevaluated
(C++11) context
(function template)

2022.07.31 http://cppreference.com

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.