128

autoC++ 14標準では、ジェネリックラムダはどのように機能しますか(引数タイプとしてのキーワード)?

異なる引数の型ごとに、コンパイラが同じ本体で型を置き換えた新しい関数を生成する C++ テンプレートに基づいていますか (コンパイル時のポリモーフィズム)、または Java のジェネリック (型消去) に似ていますか?

コード例:

auto glambda = [](auto a) { return a; };
4

3 に答える 3

148

汎用ラムダは で導入されましたC++14

簡単に言えば、ラムダ式で定義されたクロージャー型には、 のラムダの通常の非テンプレート呼び出し演算子ではなく、テンプレート化された呼び出し演算子がありC++11ます (もちろん、autoパラメーター リストに少なくとも 1 回現れる場合)。

だからあなたの例:

auto glambda = [] (auto a) { return a; };

glambdaこのタイプのインスタンスを作成します:

class /* unnamed */
{
public:
    template<typename T>
    T operator () (T a) const { return a; }
};

C++14 標準ドラフト n3690 のパラグラフ 5.1.2/5 は、特定のラムダ式のクロージャー型の呼び出し演算子がどのように定義されるかを指定します。

非ジェネリック ラムダ式のクロージャー型には、パブリック インライン関数呼び出し演算子 (13.5.4) があり、そのパラメーターと戻り値の型は、それぞれラムダ式の parameter-declaration-clause と Trailing-return-type によって記述されます。ジェネリック ラムダの場合、クロージャ型にはパブリック インライン関数呼び出し演算子メンバー テンプレート (14.5.2) があり、そのテンプレート パラメータ リストは、ラムダのパラメータ宣言句での auto の出現ごとに 1 つの発明型テンプレート パラメータで構成されます。登場順に. 対応するパラメーター宣言が関数パラメーター パック (8.3.5) を宣言する場合、発明された型テンプレート パラメーターはパラメーター パックです。関数呼び出し演算子テンプレートの戻り値の型と関数パラメーターは、ラムダ式の末尾の戻り値の型とパラメーター宣言節から派生し、パラメーター宣言節の decl-specifiers 内の auto の各出現を次の名前に置き換えます。対応する発明されたテンプレートパラメータ。

ついに:

異なる引数の型ごとにコンパイラが同じ本体で型が変更された関数を生成するテンプレートに似ていますか、それともJavaのジェネリックに似ていますか?

上記の段落で説明したように、ジェネリック ラムダは、テンプレート化された呼び出し演算子を使用した一意の名前のないファンクターの単なる構文糖衣です。それはあなたの質問に答えるはずです:)

于 2013-06-21T11:02:00.407 に答える