C ++ 14にすでに汎用ラムダがある場合に、C ++ 20に導入されたテンプレートラムダの必要性は何ですか?


99

以下を書くことを可能にする一般的なラムダを導入しました:

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

このジェネリックなラムダはfunc、テンプレート関数funcが機能するのと同じように機能することは明らかです。

C ++委員会が汎用ラムダのテンプレート構文を追加することにしたのはなぜですか?


5
引数や戻り値の型とは異なるテンプレート型を使用する必要がある場合はどうなりますか?そして、それが体内で必要な場合はどうなりますか?
一部のプログラマー、

これは興味深いユースケースだと聞いたことがあります。
Max Langhof

回答:


115

C ++ 14ジェネリックラムダは、operator ()次のようなファンクターを生成する非常に優れた方法です。

template <class T, class U>
auto operator()(T t, U u) const;

しかし、これは好きではありません:

template <class T>
auto operator()(T t1, T t2) const; // Same type please

これも好きではありません:

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please

これも好きではありません(ただし、実際に使用するには少し注意が必要です)。

template <class T>
auto operator()() const; // No deduction

C ++ 14ラムダは問題ありませんが、C ++ 20を使用すると、これらのケースを簡単に実装できます。


2
素敵で簡潔です。これを追加するだけです:最初の(同じ型)は(auto a, decltype(a) b)C ++ 14で解決できます。
セバスチャンマッハ

13
@SebastianMachほぼ。そのソリューションでbは演繹されず、その引数はa代わりにの型に暗黙的に変換されます。
Quentin

32

C ++ 20ではテンプレート化されたラムダを使用できるため、SFINAE式よりも簡単な方法で型を制限できます。

auto lambda = []<typename T>(std::vector<T> t){};

このラムダはベクタータイプでのみ機能します。


8
consteval新しい構文とどのように関連していますか?かっこいいですが、関連性はありません。
StoryTeller-Unslander Monica

それは質問への答えよりもC ++ 20がラムダ式に何を追加するかについての情報です
Antoine Morrier

24

提案 C ++ 20に受け入れられた例と長いモチベーション部を有しています。それの前提はこれです:

ジェネリックラムダを定義するための現在の構文が作成者によって不十分であると見なされるのには、いくつかの主要な理由があります。その要点は、通常の関数テンプレートで簡単に実行できるいくつかのことは、一般的なラムダで実行するにはかなりのフープジャンプが必要か、まったく実行できないということです。通常の関数テンプレートと同様に。

以下はかなりの数の例です。


21

C ++ 20で導入されたラムダ用の新しい「使い慣れたテンプレート構文」により 、C ++ 17の代替物と比較してfor_types 、  などの構成要素が  for_range実行可能で読みやすくなります。

(ソース:C ++ 20ラムダを使用したコンパイル時の反復

C ++ 14とC ++ 17の両方の汎用ラムダで実行できるもう1つの興味深いことはoperator() 、テンプレートパラメーターを明示的に渡すことによって直接呼び出す  ことです。

C ++ 14:

   auto l = [](auto){ };
   l.template operator()<int>(0);

C ++ 20:

  auto l = []<typename T>(){ };
  l.template operator()<int>();

上記のC ++ 14の例はまったく役に立ちません。operator() 引数に名前を付けてを使用しないと、ラムダの本体で提供され  ている型を参照する方法はありません  decltype。さらに、引数が必要ない場合でも、引数を渡す必要があります。

C ++ 20の例は、ラムダの本体でTに簡単にアクセスできることと、nullaryラムダを任意にテンプレート化できることを示しています。これは、前述のコンパイル時構成の実装に非常に役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.