名前付き要件: Callable
提供: cppreference.com
型 Callable は、 (std::function、 std::bind、 std::thread::thread などによって使用される) INVOKE 操作が適用可能な型です。 この操作はライブラリ関数 std::invoke を用いて明示的に行うことができます。 (C++17以上)
目次 |
[編集] 要件
以下の内容を満たす場合、型 T
は Callable を満たします。
-
T
型のオブジェクトf
- 適切な引数型のリスト
ArgTypes
- 適切な戻り値の型
R
が与えられたとき、以下の式が有効でなければなりません。
式 | 要件 |
---|---|
INVOKE<R>(f, std::declval<ArgTypes>()...) | この式が未評価文脈において well-formed である。 |
ただし INVOKE<R>(f, t1, t2, ..., tN) は R
が void (または cv 修飾された void) であれば static_cast<void>(INVOKE(f, t1, t2, ..., tN))、そうでなければ R
に暗黙に変換された INVOKE(f, t1, t2, ..., tN) です。
ただし INVOKE(f, t1, t2, ..., tN) は以下のように定義されます。
-
f
がク��スT
のメンバ関数ポインタの場合、
- std::is_base_of<T, std::remove_reference_t<decltype(t1)>>::value が true であれば、 INVOKE(f, t1, t2, ..., tN) は (t1.*f)(t2, ..., tN) と同等です。
- そうでなく、 std::remove_cvref_t<decltype(t1)> が std::reference_wrapper の特殊化であれば、 INVOKE(f, t1, t2, ..., tN) は (t1.get().*f)(t2, ..., tN) と同等です。 (C++17以上)
- そうでなく、
t1
が上の項目を満たさなければ、 INVOKE(f, t1, t2, ..., tN) は ((*t1).*f)(t2, ..., tN) と同等です。
- そうでなく、 N == 1 であり
f
がクラスT
のデータメンバポインタの場合、
- std::is_base_of<T, std::remove_reference_t<decltype(t1)>>::value が true であれば、 INVOKE(f, t1) は t1.*f と同等です。
- そうでなく、 std::remove_cvref_t<decltype(t1)> が std::reference_wrapper の特殊化であれば、 INVOKE(f, t1) は t1.get().*f と同等です。 (C++17以上)
- そうでなく、
t1
が上の項目を満たさなければ、 INVOKE(f, t1) は (*t1).*f と同等です。
- そうでなければ、 INVOKE(f, t1, t2, ..., tN) は f(t1, t2, ..., tN) と同等です (つまり、
f
は FunctionObject です)。
[編集] ノート
メンバ関数ポインタおよびデータメンバポインタの場合、 t1
は普通のポインタでも構いませんし、 std::unique_ptr や std::shared_ptr のような operator*
をオーバーロードしたクラス型のオブジェクトでも構いません。
データメンバポインタは、関数呼び出しは行われませんが、 Callable です。
[編集] 標準ライブラリ
さらに、以下の標準ライブラリの機能は (FunctionObject だけでなく) 任意の Callable な型を受理します。
std::function | |
std::bind | |
std::result_of | |
std::thread::thread | |
std::call_once | |
std::async | |
std::packaged_task | |
std::reference_wrapper |
[編集] 欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
DR | 適用先 | 発行時の動作 | 正しい動作 |
---|---|---|---|
LWG 2420 | C++11 | when R is void, the result must be implicitly convertible to void (which is impossible) | the result is explicitly converted to void when R is cv void |
[編集] 関連項目
型が指定された引数型で (std::invoke によるかのように) 呼ぶことが可能かどうか調べます (クラステンプレート) |