Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are function-local typedefs visible inside C++0x lambdas?

I've run into a strange problem. The following simplified code reproduces the problem in MSVC 2010:

template <typename T>
struct dummy
{
    static T foo(void) { return T(); }
};

int main(void)
{
    typedef dummy<bool> dummy_type;
    auto x = []{ bool b = dummy_type::foo(); };
    // auto x = []{ bool b = dummy<bool>::foo(); }; // works
}

The typedef I created locally in the function doesn't seem to be visible in the lambda. If I replace the typedef with the actual type, it works as expected.

Here are some other test cases:

// crashes the compiler, credit to Tarydon
int main(void)
{
    struct dummy {};

    auto x = []{ dummy d; };
}

// works as expected
int main(void)
{
    typedef int integer;

    auto x = []{ integer i = 0; };
}

I don't have g++ available to test it, right now. Is this some strange rule in C++0x, or just a bug in the compiler?

From the results above, I'm leaning towards bug. Though the crash is definitely a bug.


For now, I have filed two bug reports.

All code snippets above should compile. The error has to do with using the scope resolution on locally defined scopes. (Spotted by dvide.)

And the crash bug has to do with... who knows. :)


Update

According to the bug reports, they have both been fixed for the next release of Visual Studio 2010. (Though this doesn't seem to be the case; VS11 perhaps.)

like image 825
GManNickG Avatar asked Jan 23 '10 05:01

GManNickG


2 Answers

From n3000, 5.1.2/6,

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), … the compound-statement is considered in the context of the lambda-expression.

Not surprisingly, the local type should be visible.

like image 69
Potatoswatter Avatar answered Jan 11 '23 05:01

Potatoswatter


Function-local enums cannot be detected by lambdas either.

int main()
{   
    enum E {A, B, C};   
    auto x = [](){ int a = A; }; 
    //auto y = [](){ E a = A; }; // this will crash the compiler
}

error C3493: 'A' cannot be implicitly captured because no default capture mode has been specified

Following is a workround, problematic-maybe though.

int main()
{   
    enum E {A, B, C};   
    auto x = [=](){ int a = A; };
    // typedef E F; 
    // auto y = [=](){ F a = A; }; // this compiles ok
}
like image 37
zwvista Avatar answered Jan 11 '23 07:01

zwvista