[解決済み] なぜ独自の匿名型を持つ言語を設計するのか?
疑問点
C++のラムダ式の特徴として、ずっと気になっていることがあります。C++ のラムダ式の型はユニークで匿名なので、単純に書き留めることができません。C++のラムダ式の型は一意であり、匿名であるため、書き出すことができない。たとえ構文的に全く同じ2つのラムダを作成したとしても、結果の型は別個であると定義されている。その結果、a) ラムダはコンパイル時にオブジェクトと一緒に型が渡せるようなテンプレート関数にしか渡すことができない。
std::function<>
.
しかし、これはC++がそうしているだけで、私はこの言語の厄介な機能として片付けようと思っていました。しかし、Rust も同じようで、Rust の各関数またはラムダはユニークな無名型を持っていることを知りました。そして今、私は不思議に思っている。なぜでしょうか?
そこで、私の質問はこれです。
言語設計者の視点から、言語に一意な無名型の概念を導入する利点は何でしょうか?
どのように解決するのですか?
多くの標準 (特に C++) は、コンパイラーに要求することを最小限に抑えるというアプローチをとっています。 率直に言って、すでに十分に要求しています! 動作させるために何かを指定する必要がない場合、実装を定義したままにする傾向があります。
ラムダが匿名でないのであれば、我々はそれを定義しなければならないでしょう。 これは、変数がどのように捕捉されるかについて多くを語らなければならないだろう。 ラムダの場合について考えてみましょう
[=](){...}
. 型は実際にラムダによって捕捉された型を指定する必要があり、それを決定することは自明ではないかもしれません。 また、コンパイラが変数の最適化に成功した場合はどうだろうか? 考えてみましょう。
static const int i = 5;
auto f = [i]() { return i; }
最適化するコンパイラーは
i
の値が 5 であることを認識し、これを
auto f = []() { return 5; }
. しかし、型が匿名でない場合、これは型を変更する可能性があります
または
を格納し、コンパイラがより少なく最適化するよう強制します。
i
を保存するように強制します。 これは、ラムダが行うことを意図していない、複雑でニュアンスのある全体の袋です。
そして、実際に非匿名型が必要な場合は、いつでもクロージャクラスを自分で構築し、ラムダ関数ではなくファンクタで作業することができます。 このように、ラムダは99%のケースを処理し、1%のケースではあなた自身の解決策をコード化するようにすることができるのです。
Deduplicatorはコメントで、私が匿名性と同じくらい一意性を扱っていないことを指摘しました。 私は一意性の利点についてあまり確信していませんが、型が一意である場合、次の動作が明確であることは注目に値します (アクションは 2 回インスタンス化されます)。
int counter()
{
static int count = 0;
return count++;
}
template <typename FuncT>
void action(const FuncT& func)
{
static int ct = counter();
func(ct);
}
...
for (int i = 0; i < 5; i++)
action([](int j) { std::cout << j << std::endl; });
for (int i = 0; i < 5; i++)
action([](int j) { std::cout << j << std::endl; });
もし型が一意でなかったら、この場合どのような動作が起こるかを指定しなければならないでしょう。 それは厄介なことかもしれません。 匿名性のトピックで提起された問題のいくつかは、一意性のこのケースでも頭をもたげます。
関連
-
[解決済み】構造体のベクター初期化について
-
[解決済み】coutはstdのメンバではない
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み] Scalaのタイプラムダとその利点とは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】'cout'は型名ではない
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された