6

The following example demonstrates the problem I encountered in VC++ 2010:

class Foo
{
    template<class T>
    static T foo(T t) { return t; }

public:
    void test()
    {
        auto lambda = []() { return foo(1); }; // call to Foo::foo<int>
        lambda();
    }
};

VC++ produces: error C3861: 'foo': identifier not found

If I qualify the call to foo: Foo::foo(1); then this example compiles with a warning: warning C4573: the usage of 'Foo::foo' requires the compiler to capture 'this' but the current default capture mode does not allow it

What does the standard say about this case? Should unqualified name be found? Does the qualified name require capturing this?

Xeo
  • 129,499
  • 52
  • 291
  • 397
Gene Bushuyev
  • 5,512
  • 20
  • 19
  • Hm, that's weird. It's static, so it shouldn't require `this`. I suspect it's compiler bug and that not finding it is side-effect of compiler thinking it needs `this` to use it. – Jan Hudec Sep 02 '11 at 08:25
  • This happens with g++ as well so it doesn't seem like a bug. If you change it to [&]() instead of []() then this compiles fine but that's because it takes the this by reference. – DrYap Sep 02 '11 at 08:34
  • Having said that [another thread](http://stackoverflow.com/questions/4940259/c0x-lambdas-require-capturing-this-to-call-static-member-function) says it is a bug. – DrYap Sep 02 '11 at 08:37

2 Answers2

4

Microsoft has been seeing this problem reported in a number of cases. See:

Scope Resolution with lambdas interferes with namespace and type resolution

Template resolution in lambdas

As you've found out, explicit resolution allows it to find the name. There is an additional warning about this which is also a compiler error (name resolution doesn't require access to this, though I can see how a compiler implementation might require it) - it's a separate bug though. Microsoft has confirmed this to be a bug and have apparently prepared a fix for the next release.

ex0du5
  • 2,586
  • 1
  • 14
  • 14
2

The following compiles fine. It seems to me that this must just be a VS bug with templates.

struct Foo {
    static void foo() {}
    void bar() {
        auto f = []() { foo(); };
        f();
    }
};
bames53
  • 86,085
  • 15
  • 179
  • 244
  • What compiler did you try? It seems the result varies depending on compiler, so it's important to know the standard conforming behavior. – Gene Bushuyev Sep 02 '11 at 19:56
  • @Gene : VC++ 2010 implemented lambdas pre-[N2927](http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2927.pdf), so it is **not** conformant to the FDIS' wording. – ildjarn Sep 02 '11 at 23:15