std::apply_result
| Defined in header <type_traits>
|
||
template< class Fn, class Tuple >
class apply_result;
|
(since C++26) | |
Deduces the return type of an INVOKE expression.
Let /*ELEMS-OF*/(T) be the parameter pack std::get<N>(std::declval<T>()), where N is the pack of std::size_t template arguments of the specialization of std::index_sequence denoted by std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>.
If tuple-like<Tuple> is true and the expression
/*INVOKE*/(std::declval<Fn>(), /*ELEMS-OF*/(Tuple)...) is well-formed when treated as an unevaluated operand, the member typedef type denotes the type decltype(/*INVOKE*/(declval<Fn>(), /*ELEMS-OF*/(Tuple)...)); otherwise, there is no member type.
Access checking is performed as if in a context unrelated to Fn and Tuple. Only the validity of the immediate context of the expression is considered.
The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and can result in the program being ill-formed.
If Fn or Tuple is not a complete type, (possibly cv-qualified) void, or an array of unknown bound, the behavior is undefined.
If an instantiation of a template above depends, directly or indirectly, on an incomplete type, and that instantiation could yield a different result if that type were hypothetically completed, the behavior is undefined.
If the program adds specializations for any of the templates described on this page, the behavior is undefined.
Member types
| Member type | Description |
type
|
the return type of the Callable type Fn if invoked with the arguments given in Tuple. Only defined if Fn can be called with the arguments in Tuple in unevaluated context.
|
Helper types
template< class Fn, class Tuple >
using apply_result_t = apply_result<Fn, Tuple>::type;
|
(since C++26) | |
Possible implementation
namespace detail
{
template<std::size_t I, class T>
using element_at = decltype(std::get<I>(std::declval<T>()));
template<class Fn, class T, std::size_t ... I>
constexpr auto apply_impl(Fn&& f, T&& t, std::index_sequence<I...>)
noexcept (std::is_nothrow_invocable_v<Fn, element_at<I, T >...>)
-> std::invoke_result_t<Fn, element_at<I, T>...>
{
return std::invoke(std::forward<Fn>(f), std::get<I>(std::forward<T>(t))...);
}
template<class Fn, class Tuple>
using apply_result_t = decltype(apply_impl(
std::declval<Fn>(),
std::declval<Tuple>(),
std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>())
);
template <class Fn, class Tuple>
struct apply_result_impl {}; // exposition-only
template<class Fn, class Tuple>
requires requires { typename std::apply_result_t<Fn, Tuple>; }
struct apply_result_impl<Fn, Tuple >
{
using type = std::apply_result_t<Fn, Tuple>;
};
} // namespace detail
template<class Fn, class Tuple>
struct apply_result : detail::apply_result_impl<Fn, Tuple>{};
Notes
std::apply_result (and the corresponding alias std::apply_result_t) is used in the return type of std::apply.(since C++26)
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_reflection |
202506L |
(C++26) | <meta>: Reflection library support. |
Examples
#include <type_traits>
struct S
{
double operator()(char, int&);
float operator()(int) { return 1.0f; }
};
int main()
{
std::apply_result_t<S, char, int&> a{3.14};
static_assert(std::is_same_v<decltype(a), double>);
std::apply_result_t<S, int> b{2.71f};
static_assert(std::is_same_v<decltype(b), float>);
}
See also
(C++17) |
calls a function with a tuple of arguments (function template) |
(C++17)(C++23) |
invokes any Callable object with given arguments and possibility to specify return type(since C++23) (function template) |
(C++11)(removed in C++20)(C++17) |
deduces the result type of invoking a callable object with a set of arguments (class template) |
(C++11) |
obtains a reference to an object of the template type argument for use in an unevaluated context (function template) |
(C++20)(C++20) |
specifies that a callable type can be invoked with a given set of argument types (concept) |
(C++17)(C++17)(C++17)(C++17) |
checks if a type can be invoked (as if by std::invoke) with the given argument types (class template) |
(C++26)(C++26)(C++26)(C++26) |
checks if the reflected type can be invoked (as if by std::invoke) with the given argument types (function template) |
(C++26)(C++26) |
checks if a type can be invoked (as if by std::invoke) with the given tuple of arguments (class template) |
(C++26) |
deduces the result type of invoking a callable object with the given reflected tuple of arguments (function) |