次のコードを検討してください。
#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
か?もしそうなら、標準のどの部分がこれを許可しますか?