2

I have a lambda inside of a function that is capturing with [&] and then using a local static variable inside the lambda. I'm not sure if this valid to begin with, but this compiles and links fine:

void Foo()
{
    static int i = 5;

    auto bar = [&]()
    {
        i++;
    };

    bar();
}

int main()
{
    Foo();
}

But by making Foo a templated function:

template <typename T>
void Foo()
{
    static int i = 5;

    auto bar = [&]()
    {
        i++;
    };

    bar();
}

int main()
{
    Foo<int>();
}

I get the following error:

g++-4.7 -std=c++11 main.cpp
/tmp/cctjnzIT.o: In function 'void Foo()::{lambda()#1}::operator()() const':
main.cpp:(.text+0x1a): undefined reference to 'i'
main.cpp:(.text+0x23): undefined reference to 'i'
collect2: error: ld returned 1 exit status

So, I have two questions:

  1. Is using i in the first example even valid c++?
  2. If #1, then what is wrong with the second example? Or is this a gcc bug?
JaredC
  • 5,150
  • 1
  • 20
  • 45
  • Technically, only variables with automatic storage duration are "captured". In both examples, the reference to `i` is just an ordinary valid lvalue use. – aschepler Mar 01 '13 at 19:22

2 Answers2

4

1) Yes, you can even drop & from definition because static is always accessible in lambda function. 2) It is bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54276

JaredC
  • 5,150
  • 1
  • 20
  • 45
Yankes
  • 1,958
  • 19
  • 20
-2

1) Yes, assuming you're intending to have 'i''s value persist between calls.

2) It's not a bug in the compiler. The static instance variable needs to also be defined via a template. Please refer to this post.

Community
  • 1
  • 1
john.pavan
  • 910
  • 4
  • 6
  • That post is about static class members, not statics local to functions. How do I explicitly refer to those? – JaredC Mar 01 '13 at 18:21
  • I think you end up with a problem. Mainly b/c each template specialization is instantiated when you use it (and therefore you get multiple instances of your static variable). – john.pavan Mar 01 '13 at 18:30