- functional[meta header]
- function template[meta id-type]
- std[meta namespace]
- cpp17[meta cpp]
namespace std {
template <class F, class... Args>
invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
noexcept(is_nothrow_invocable_v<F, Args...>); //C++17
template <class F, class... Args>
constexpr invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
noexcept(is_nothrow_invocable_v<F, Args...>); //C++20
}
- invoke_result_t[link /reference/type_traits/invoke_result.md]
- is_nothrow_invocable_v[link /reference/type_traits/is_nothrow_invocable.md]
関数呼び出し可能なオブジェクトf
とその引数args...
の組み合わせでINVOKE要件に従った関数呼び出しを行う。
INVOKE要件とはC++における関数呼び出しという性質を抽象化しまとめた概念であり、invoke
はその実体化、すなわち関数呼び出しという操作を統一したものである。
型F
およびArgs...
の組み合わせでINVOKE要件に従った関数呼び出しが可能であり、オーバーロード解決の結果が曖昧にならないこと。そうでない場合はコンパイルエラーとなる。
f
-- Callable オブジェクト(関数ポインタ/参照・関数オブジェクト・メンバポインタ)args...
--f
に与える引数列。f
がメンバポインタである場合は対応するクラスのオブジェクト(もしくはそのreference_wrapper)がargs...
の先頭になければならない
f
とargs...
によりINVOKE要件に従った関数呼び出しを行い、その結果を戻り値として返す。
f
のargs...
による関数呼び出しに際して例外を投げない(is_nothrow_invocable_v<F, Args...>
== true
)ならば、この関数も例外を投げない。
#include <iostream>
#include <functional>
struct functor {
auto operator()() -> int {
return 10;
}
auto operator()(int n) -> int {
return n;
}
};
struct has_member {
auto member_function(int n) -> int {
return n;
}
int member_object;
};
auto f(int) -> double {
return 3.14159265359;
}
auto g(int) -> double {
return 2.71828182846;
}
auto g(int,int) -> double {
return 3.14159265359;
}
int main()
{
functor fobj{};
//関数オブジェクト呼び出し
std::cout << std::invoke(fobj) << std::endl;
std::cout << std::invoke(fobj, 100) << std::endl;
has_member obj{25};
//メンバ関数呼び出し
std::cout << std::invoke(&has_member::member_function, obj, 50) << std::endl;
//メンバ変数呼び出し
std::cout << std::invoke(&has_member::member_object, obj) << std::endl;
auto ref = std::ref(obj);
//reference_wrapperからのメンバ関数呼び出し
std::cout << std::invoke(&has_member::member_function, ref, 50) << std::endl;
//reference_wrapperからのメンバ変数呼び出し
std::cout << std::invoke(&has_member::member_object, ref) << std::endl;
//関数呼び出し
std::cout << std::invoke(f, 10) << std::endl;
//フリー関数は一度関数ポインタにしないとオーバーロード解決できない
std::cout << std::invoke((double(*)(int))g, 10) << std::endl;
std::cout << std::invoke((double(*)(int, int))g, 10, 10) << std::endl;
//コンパイルエラー
//std::cout << std::invoke(g, 10) << std::endl;
}
- std::invoke[color ff0000]
10
100
50
25
50
25
3.14159
2.71828
3.14159
- C++17
- Clang: ??
- GCC: ??
- Visual C++: 2015, 2017