Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable To Resolve Name In Lambda When Naming Nested Class

I'm using MSVC10.

I have a class C which is nested in class B, which in turn is nested in class A. B has a member variable of type C, and A has a vector of Bs. Like so:

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

Within A I have a member function which uses for_each with a lambda, to iterate over the vector<B>.

In that lambda I try to get a reference to the B and the C (separately):

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_;
    });
}

The code: const B::C& c = b.c_; results in a compiler error, "'B' : is not a class or namespace name" even though the compiler had no problem accepting const B& b = that;

Is this syntax allowed by the language?

If I change it to: const A::B::C& c = b.c_; the compiler accepts it.

Here is a complete example for you to play with:

#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();
}
like image 694
John Dibling Avatar asked Jul 12 '26 18:07

John Dibling


1 Answers

It's a bug in the compiler. The code compiles fine with MSVC 2012 RC. I believe the pertinent bug is this one.

And the pertinent part of the standard is [expr.prim.lambda] 5.1.2 clause 7:

The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator, but for purposes of name lookup (3.4), determining the type and value of this (9.3.2) and transforming id-expressions referring to non-static class members into class member access expressions using (*this) (9.3.1), the compound-statement is considered in the context of the lambda-expression.

like image 152
Jesse Good Avatar answered Jul 14 '26 11:07

Jesse Good



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!