1. ホーム
  2. c++

[解決済み] グローバルラムダを使用しない理由は何ですか?

2023-02-24 20:50:39

質問

自分自身の内部で捕捉しないラムダを使用する関数がありました。

void foo() {
  auto bar = [](int a, int b){ return a + b; }

  // code using bar(x,y) a bunch of times
}

ラムダで実装された機能は他の場所で必要になったので、ラムダを foo() からグローバル/名前空間スコープにラムダを持ち出すつもりです。ラムダのままにしてコピーペーストのオプションにするか、適切な関数に変更するかです。

auto bar = [](int a, int b){ return a + b; } // option 1
int bar(int a, int b){ return a + b; } // option 2

void foo() {
  // code using bar(x,y) a bunch of times
}

これを適切な関数に変更するのは簡単なことですが、何か理由があるのではと思いました。 ではなく をラムダとして残しておく理由はあるのでしょうか?通常のグローバル関数の代わりに、あらゆる場所でラムダを使用しない理由はあるのでしょうか?

どのように解決するのですか?

グローバルラムダを使用しない非常に重要な理由が1つあります。

C++の通常の関数構文は、C言語の時代から存在しています。プログラマは、この構文が何を意味し、どのように動作するかを何十年も前から知っていました(ただし、関数からポインタへの崩壊というのは、熟練プログラマでさえ時々噛み付くことがあります)。C++ プログラマーが、まったくの初心者を超えて関数の定義を目にしたとき、彼らは自分が何を得ているのかを知っています。

グローバルラムダは全く別の生き物です。通常の関数とは異なる振る舞いをします。ラムダはオブジェクトですが、関数はそうではありません。ラムダには型がありますが、その型は関数の型とは別物です。といった具合です。

これで、他のプログラマーとのコミュニケーションのハードルが上がりましたね。C++プログラマーは、この関数が何をしているのか理解しようとするならば、ラムダを理解する必要があります。そして、そう、これは2019年のことですから、まともなC++プログラマーならラムダがどのようなものか見当がつくはずです。しかし、それはまだ高いハードルです。

そして、たとえ理解できたとしても、そのプログラマの頭に浮かぶ疑問は...なぜこのコードの作者はそのように書いたのか?そして、その疑問に対する良い答えを持っていない場合(例えば、明示的に が欲しい のようにオーバーロードと ADL を禁止しているため)、共通のメカニズムを使用する必要があります。

適切な場合には、新しいものよりも予想される解決策を優先してください。あなたの主張を伝えるのに最も複雑でない方法を使用する。