Defined in header
<functional> | ||
---|---|---|
template< class F, class... ArgTypes> std::result_of_t<F&&(ArgTypes&&...)> invoke(F&& f, ArgTypes&&... args); | (since C++17) |
Invoke the Callable
object f
with the parameters args
. As by INVOKE(std::forward<F>(f), std::forward<Args>(args)...)
.
where INVOKE(f, t1, t2, ..., tN) is defined as follows:
f
is a pointer to member function of class T
: std::is_base_of<T, std::decay_t<decltype(t1)>>::value
is true
, then INVOKE(f, t1, t2, ..., tN)
is equivalent to (t1.*f)(t2, ..., tN)
std::decay_t<decltype(t1)>
is a specialization of std::reference_wrapper
, then INVOKE(f, t1, t2, ..., tN)
is equivalent to (t1.get().*f)(t2, ..., tN)
t1
does not satisfy the previous items, then INVOKE(f, t1, t2, ..., tN)
is equivalent to ((*t1).*f)(t2, ..., tN)
. f
is a pointer to data member of class T
: std::is_base_of<T, std::decay_t<decltype(t1)>>::value
is true
, then INVOKE(f, t1)
is equivalent to t1.*f
std::decay_t<decltype(t1)>
is a specialization of std::reference_wrapper
, then INVOKE(f, t1)
is equivalent to t1.get().*f
t1
does not satisfy the previous items, then INVOKE(f, t1)
is equivalent to (*t1).*f
INVOKE(f, t1, t2, ..., tN)
is equivalent to f(t1, t2, ..., tN)
(that is, f
is a FunctionObject
) f | - | Callable object to be invoked |
args | - | arguments to pass to f |
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> constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value; template <class Base, class T, class Derived, class... Args> auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args) noexcept(noexcept((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...))) -> std::enable_if_t<std::is_function_v<T> && std::is_base_of_v<Base, std::decay_t<Derived>>, decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...))> { return (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...); } template <class Base, class T, class RefWrap, class... Args> auto INVOKE(T Base::*pmf, RefWrap&& ref, Args&&... args) noexcept(noexcept((ref.get().*pmf)(std::forward<Args>(args)...))) -> std::enable_if_t<std::is_function_v<T> && is_reference_wrapper_v<std::decay_t<RefWrap>>, decltype((ref.get().*pmf)(std::forward<Args>(args)...))> { return (ref.get().*pmf)(std::forward<Args>(args)...); } template <class Base, class T, class Pointer, class... Args> auto INVOKE(T Base::*pmf, Pointer&& ptr, Args&&... args) noexcept(noexcept(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...))) -> std::enable_if_t<std::is_function_v<T> && !is_reference_wrapper_v<std::decay_t<Pointer>> && !std::is_base_of_v<Base, std::decay_t<Pointer>>, decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...))> { return ((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...); } template <class Base, class T, class Derived> auto INVOKE(T Base::*pmd, Derived&& ref) noexcept(noexcept(std::forward<Derived>(ref).*pmd)) -> std::enable_if_t<!std::is_function_v<T> && std::is_base_of_v<Base, std::decay_t<Derived>>, decltype(std::forward<Derived>(ref).*pmd)> { return std::forward<Derived>(ref).*pmd; } template <class Base, class T, class RefWrap> auto INVOKE(T Base::*pmd, RefWrap&& ref) noexcept(noexcept(ref.get().*pmd)) -> std::enable_if_t<!std::is_function_v<T> && is_reference_wrapper_v<std::decay_t<RefWrap>>, decltype(ref.get().*pmd)> { return ref.get().*pmd; } template <class Base, class T, class Pointer> auto INVOKE(T Base::*pmd, Pointer&& ptr) noexcept(noexcept((*std::forward<Pointer>(ptr)).*pmd)) -> std::enable_if_t<!std::is_function_v<T> && !is_reference_wrapper_v<std::decay_t<Pointer>> && !std::is_base_of_v<Base, std::decay_t<Pointer>>, decltype((*std::forward<Pointer>(ptr)).*pmd)> { return (*std::forward<Pointer>(ptr)).*pmd; } template <class F, class... Args> auto INVOKE(F&& f, Args&&... args) noexcept(noexcept(std::forward<F>(f)(std::forward<Args>(args)...))) -> std::enable_if_t<!std::is_member_pointer_v<std::decay_t<F>>, decltype(std::forward<F>(f)(std::forward<Args>(args)...))> { return std::forward<F>(f)(std::forward<Args>(args)...); } } // namespace detail template< class F, class... ArgTypes > auto invoke(F&& f, ArgTypes&&... args) // exception specification for QoI noexcept(noexcept(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...))) -> decltype(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...)) { return detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...); }
Implement the basic functionality of std::mem_fn
.
#include <functional> template< class PM > class mem_fn_t { PM p; public: mem_fn_t(PM p):p(p){} template<class... Args> decltype(auto) operator()(Args&&... args) { return std::invoke(p, std::forward<Args>(args)...); } }; template< class R, class T > auto mem_fn(R T::* pm){ mem_fn_t<R T::*> t {pm}; return t; }
(C++11)
| creates a function object out of a pointer to a member (function template) |
(C++11)
| deduces the return type of a function call expression (class template) |
(C++17)
| checks if a type can be invoked (as if by std::invoke ) with the given argument types (class template) |
(C++17)
| calls a function with a tuple of arguments (function template) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/utility/functional/invoke