Пространства имён
Варианты
Действия

std::invoke, std::invoke_r

Материал из cppreference.com
< cpp‎ | utility‎ | functional
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм(C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования(C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
Объекты функции
Функции обёртки
(C++11)
(C++11)
Применение частичных функций
(C++20)(C++23)
(C++11)
Вызов функции
invokeinvoke_r
(C++17)(C++23)
Объект идентичности функции
(C++20)
Обёртки ссылок
(C++11)(C++11)
Прозрачные обёртки операторов
(C++14)
(C++14)
(C++14)
(C++14)  
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
Отрицатели
(C++17)
Искатели
Ограниченные компараторы
Старые привязки и адаптеры
(до C++17*)
(до C++17*)
(до C++17*)
(до C++17*)
(до C++17*)(до C++17*)(до C++17*)(до C++17*)
(до C++20*)
(до C++20*)
(до C++17*)(до C++17*)
(до C++17*)(до C++17*)

(до C++17*)
(до C++17*)(до C++17*)(до C++17*)(до C++17*)
(до C++20*)
(до C++20*)
 
Определено в заголовочном файле <functional>
(1)
template<class F, class... Args>

std::invoke_result_t<F, Args...>

    invoke( F&& f, Args&&... args)noexcept(/* смотрите ниже */);
(начиная с C++17)
(до C++20)
template<class F, class... Args>

constexprstd::invoke_result_t<F, Args...>

    invoke( F&& f, Args&&... args)noexcept(/* смотрите ниже */);
(начиная с C++20)
template<class R, class F, class... Args>
constexpr R invoke_r( F&& f, Args&&... args)noexcept(/* смотрите ниже */);
(2)(начиная с C++23)
1) Вызвать объект Callablef с параметрами args, как INVOKE(std::forward<F>(f), std::forward<Args>(args)...). Эта перегрузка участвует в разрешении перегрузки, только если std::is_invocable_v<F, Args...> равно true.
2) Вызвать объект Callablef с параметрами args, как INVOKE<R>(std::forward<F>(f), std::forward<Args>(args)...). Эта перегрузка участвует в разрешении перегрузки, только если std::is_invocable_r_v<R, F, Args...> равно true.

Содержание

[править]Параметры

f Callable объект для вызова
args аргументы для передачи f

[править]Возвращаемое значение

1) Значение, возвращаемое f.
2) Значение, возвращаемое f, неявно преобразуется в R, если R не равно void. Иначе ничего.

[править]Исключения

1)
спецификация noexcept:  
noexcept(std::is_nothrow_invocable_v<F, Args...>)
2)
спецификация noexcept:  
noexcept(std::is_nothrow_invocable_r_v<R, F, Args...>)

[править]Возможная реализация

invoke
namespace detail {template<class>constexprbool is_reference_wrapper_v =false;template<class U>constexprbool is_reference_wrapper_v<std::reference_wrapper<U>>=true;   template<class C, class Pointed, class T1, class... Args>constexpr decltype(auto) invoke_memptr(Pointed C::* f, T1&& t1, Args&&... args){ifconstexpr(std::is_function_v<Pointed>){ifconstexpr(std::is_base_of_v<C, std::decay_t<T1>>)return(std::forward<T1>(t1).*f)(std::forward<Args>(args)...);elseifconstexpr(is_reference_wrapper_v<std::decay_t<T1>>)return(t1.get().*f)(std::forward<Args>(args)...);elsereturn((*std::forward<T1>(t1)).*f)(std::forward<Args>(args)...);}else{ static_assert(std::is_object_v<Pointed>&& sizeof...(args)==0);ifconstexpr(std::is_base_of_v<C, std::decay_t<T1>>)returnstd::forward<T1>(t1).*f;elseifconstexpr(is_reference_wrapper_v<std::decay_t<T1>>)return t1.get().*f;elsereturn(*std::forward<T1>(t1)).*f;}}}// пространство имён detail   template<class F, class... Args>constexprstd::invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)noexcept(std::is_nothrow_invocable_v<F, Args...>){ifconstexpr(std::is_member_pointer_v<std::decay_t<F>>)return detail::invoke_memptr(f, std::forward<Args>(args)...);elsereturnstd::forward<F>(f)(std::forward<Args>(args)...);}
invoke_r
template<class R, class F, class... Args> requires std::is_invocable_r_v<R, F, Args...>constexpr R invoke_r(F&& f, Args&&... args)noexcept(std::is_nothrow_invocable_r_v<R, F, Args...>){ifconstexpr(std::is_void_v<R>) std::invoke(std::forward<F>(f), std::forward<Args>(args)...);elsereturn std::invoke(std::forward<F>(f), std::forward<Args>(args)...);}

[править]Примечание

Макрос тест функциональностиЗначениеСтандартКомментарий
__cpp_lib_invoke201411L(C++17)std::invoke
__cpp_lib_invoke_r202106L(C++23)std::invoke_r

[править]Пример

#include <functional>#include <iostream>#include <type_traits>   struct Foo { Foo(int num): num_(num){}void print_add(int i)const{std::cout<< num_+i <<'\n';}int num_;};   void print_num(int i){std::cout<< i <<'\n';}   struct PrintNum {void operator()(int i)const{std::cout<< i <<'\n';}};   int main(){// вызвать свободную функцию std::invoke(print_num, -9);   // вызвать лямбду std::invoke([](){ print_num(42);});   // вызвать функцию-элементconst Foo foo(314159); std::invoke(&Foo::print_add, foo, 1);   // вызвать (получить доступ к) элемент данныхstd::cout<<"num_: "<< std::invoke(&Foo::num_, foo)<<'\n';   // вызвать функциональный объект std::invoke(PrintNum(), 18);   # if defined(__cpp_lib_invoke_r)auto add =[](int x, int y){return x + y;};auto ret = std::invoke_r<float>(add, 11, 22); static_assert(std::is_same<decltype(ret), float>());std::cout<< ret <<'\n'; std::invoke_r<void>(print_num, 44);# endif}

Возможный вывод:

-9 42 314160 num_: 314159 18 33 44

[править]Смотрите также

(C++11)
создаёт объект функцию из указателя на элемент
(шаблон функции)[править]
(C++11)(удалено в C++20)(C++17)
выводит тип результата вызова вызываемого объекта с набором аргументов
(шаблон класса)[править]
проверяет, может ли тип быть вызван (как если бы std::invoke) с заданными типами аргументов
(шаблон класса)[править]
(C++17)
вызывает функцию с кортежем аргументов
(шаблон функции)[править]
close