23

次のコードを検討してください。

#include <iostream>

struct test
{
    void public_test()
    {
        [this]() { private_test(); }();
    }

private:
    void private_test()
    {
        std::cout << "test\n";
    }
};

int main()
{
    test().public_test();
}

ラムダはこれをキャプチャし、キャプチャされたオブジェクトのプライベートメソッドを呼び出します。これで、このコードはVC ++ 2012を使用してコンパイルおよび動作(印刷test)されます。これは非常に直感的で便利な動作ですが、これが標準で動作することが保証されているかどうかを知りたいです。したがって、ラムダは?を介してキャプチャされたオブジェクトへのプライベートアクセスを持っていますthisか?

私はこれを5.1.2[expr.prim.lambda]までの標準的な読みで調べようとしましたが、明確な答えを見つけることができませんでした(標準の深さにそれほど精通していませんでした)。私にとって有用だと思われた唯一の段落は

ラムダ式の型(クロージャオブジェクトの型でもあります)は、一意の名前のない非ユニオンクラス型(クロージャ型と呼ばれます)であり、そのプロパティについては以下で説明します。このクラスタイプは集合体ではありません(8.5.1)。クロージャタイプは、対応するラムダ式を含む最小のブロックスコープ、クラススコープ、または名前空間スコープで宣言されます。[注:これにより、クロージャータイプ(3.4.2)に関連付けられた名前空間とクラスのセットが決まります。ラムダ宣言子のパラメータータイプは、これらの関連する名前空間とクラスに影響を与えません。—エンドノート]

ただし、一方で、メンバー関数で定義された通常のローカルクラスタイプには、周囲のクラスへのプライベートアクセスがありません。したがって、プライベートアクセスを持つラムダは、ロ​​ーカル関数オブジェクトの単なる構文糖衣を超えてラムダをより複雑なものに引き上げます。これは、ラムダを周囲のクラスの友達にするために追加の「コンパイラマジック」が必要になるためです。

では、ラムダはキャプチャされたオブジェクトへのプライベートアクセスを持っていますthisか?もしそうなら、標準のどの部分がこれを許可しますか?

4

1 に答える 1

28

それがラムダであるという事実は関係ないと思います。ラムダが行うのは、ローカルクラスを定義することだけです。また、§11/ 2によると、「メンバー関数のローカルクラスは、メンバー関数自体がアクセスできるのと同じ名前にアクセスできます。」

于 2012-10-04T16:04:35.373 に答える