在线文档教程
C++
应用 | Utilities

std::invoke

std::invoke

Defined in header
template< class F, class... Args> std::invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) noexcept(/* see below */(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:

  • if f is a pointer to member function of class T:

Parameters

f-Callable object to be invoked
args-arguments to pass to f

Exceptions

noexcept specification:

noexcept(std::is_nothrow_invocable_v<F, Args...>)

Possible implementation

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)... }

Example

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

See also

mem_fn (C++11)creates a function object out of a pointer to a member (function template)
result_ofinvoke_result (C++11)(deprecated in C++17)(C++17)deduces the result type of invoking a callable object with a set of arguments (class template)
is_invocableis_invocable_ris_nothrow_invocableis_nothrow_invocable_r (C++17)checks if a type can be invoked (as if by std::invoke) with the given argument types (class template)
apply (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