Unary Plus 演算子を使用した Lambda オーバーロードのあいまいさの解決
C では、異なるパラメーター型を持つ複数の実装を提供することで関数をオーバーロードすることで柔軟性が得られます。コードの再利用で。ただし、ラムダ式を使用して関数を呼び出そうとする場合、ラムダが複数のオーバーロードを満たすことができる場合、あいまいさが発生する可能性があります。
あいまいさの問題
次のコード スニペットを考えてみましょう。 :
#include <functional> void foo(std::function<void()> f) { f(); } void foo(void (*f)()) { f(); } int main() { foo([](){}); // ambiguous }
ラムダ式 []() を使用した foo への最初の呼び出しは、コンパイラーがどのオーバーロードを使用するかを決定できないため、あいまいになります。 std::function と関数ポインターのオーバーロードは両方とも実行可能な候補です。
単項プラス演算子による曖昧さの解決
表記法 (この場合は単項プラス演算子)を使用すると、この曖昧さを解決できます。ラムダ式の前に単項プラスを置くことで、関数ポインター型への変換が強制されます。
foo(+[](){});
この変換により、関数ポインターは引数の型 void (*)() と完全に一致するオーバーロードになります。
単項プラス演算子
C 標準で定義されている単項プラス演算子には、次のプロパティがあります。
"単項演算子のオペランドは算術型、スコープなし列挙型、またはポインター型を持つ必要があり、結果は引数の値になります。"
ラムダの場合、算術型またはポインター型を持たないにもかかわらず、クロージャー型のプロパティにより、 void (*)() に変換されます。ラムダのクロージャ型には、ラムダの関数呼び出し演算子と同じパラメータと戻り値を持つ関数ポインタへの非明示的な変換関数があります。
関数ポインタのオーバーロードの選択
単項プラスで void (*)() への変換を強制すると、2 番目のオーバーロード void foo(void (*f)()) がオーバーロード解決ランキングで完全に一致します。これは唯一の完全一致であるため、明確に選択されます。
代替アプローチ
あるいは、曖昧さを避けるためにラムダを関数ポインター型に明示的にキャストするには、次の手順を実行します。使用できるもの:
foo(static_cast<void (*)()>([](){}));
以上がC でラムダをオーバーロードする場合、単項 Plus 演算子は曖昧さをどのように解決できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。