3

私はMSVC10を使用しています。

Cクラスにネストされているクラスがあり、クラスはクラスにネストBされていAます。 Bタイプがのメンバー変数をC持ちAvectorのがBsです。そのようです:

class A
{
  class B
  {
    string foo_;
    class C
    {
      string bar_;
    } c_;
  };
  vector<B> b_;
};

中には、ラムダAで使用するメンバー関数があり、を反復処理します。for_eachvector<B>

Bそのラムダでは、とC(別々に)への参照を取得しようとします:

void A::Run()
{
    for_each(b_.begin(), b_.end(), [](std::vector<B>::value_type& that)
    {
        const B& b = that;
        cout << b.foo_;
        const B::C& c = b.c_;   //  'B' : is not a class or namespace name
        // const A::B::C& c = b.c_; <-- THIS COMPILES
        cout << c.bar_;
    });
}

コード:コンパイラが問題なく受け入れてconst B::C& c = b.c_;、「'B':はクラス名または名前空間名ではありません」というコンパイラエラーが発生します。const B& b = that;

この構文は言語で許可されていますか?

これを次のように変更すると const A::B::C& c = b.c_;、コンパイラはそれを受け入れます。

これがあなたが遊ぶための完全な例です:

#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void foo() {}

class A
{
public: 
    void Run();

    struct B
    {
        std::string foo_;
        struct C
        {
            std::string bar_;
        } c_;
    };

    std::vector<B> b_;
};

void A::Run()
{
    for_each(b_.begin(), b_.end(), [](std::vector<B>::value_type& that)
    {
        const B& b = that;
        cout << b.foo_;
        const B::C& c = b.c_;   //  'B' : is not a class or namespace name
        // const A::B::C& c = b.c_; <-- THIS COMPILES
        cout << c.bar_;
    });
}

int main()
{
    A a;
    a.Run();
}
4

1 に答える 1

2

これはコンパイラのバグです。コードはMSVC2012RCで正常にコンパイルされます。関連するバグはこれだと思います。

そして、標準の適切な部分は[expr.prim.lambda]5.1.2節7です。

ラムダ式の複合ステートメントは、関数呼び出し演算子の関数本体(8.4)を生成しますが、名前ルックアップ(3.4)の目的で 、この(9.3.2)のタイプと値を決定し、次を参照するid式を変換します。非静的クラスメンバーを(* this)(9.3.1)を使用してクラスメンバーアクセス式に変換すると、複合ステートメントはラムダ式のコンテキストで考慮されます。

于 2012-06-20T21:30:31.413 に答える