0

What's the correct way to have an anonymous local function object access an argument of the containing method? I.e., what's the correct way to do the following:

void A::foo(B& b)
{
    struct {
        void operator()() {b.bar();}
    } func;
    func();
}

NB: This example is contrived for simplicity: the actual use-case involves applying an anonymous local function object to each element in a container to have the element act on the argument of the containing method.

Steve Emmerson
  • 7,702
  • 5
  • 33
  • 59

3 Answers3

5

You need to pass the reference/pointer of the worked-on object to the anonymous one. But since it's anonymous, you cannot declare its constructor. If you named it, you'd be able to say:

void A::foo(B& b)
{
    struct Foo{
        B& b;
        Foo(B& b) : b(b) {}
        void operator()() {b.bar();}
    } func{b};
    func();
}

That being said, in C++11 - as you tagged this question - you could use a lambda expression:

void A::foo(B& b)
{
    auto func = [&]{ b.bar(); };
    func();
}
krzaq
  • 16,240
  • 4
  • 46
  • 61
2

A function cannot access stuff from its local scope.

Lambdas get around that by capturing variables in their local scope. They copy/move/reference them. But they're not technically accessing those variables. Only lambdas can do this.

You can of course explicitly do what a lambda does implicitly. That is, have the class's constructor take a copy or reference to a variable, then initialize the object by calling that constructor. Of course, that means it cannot be an anonymous class anymore.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
0

In fact you wrote almost all correctly. Here you are

#include <iostream>

struct A
{
    void foo( const struct B &b );
};

struct B
{
    void bar() const { std::cout << "Hello A!" << std::endl; }
};

void A::foo( const B &b )
{
    struct 
    {
        void operator ()( const B &b ) const { b.bar(); }
    } func;

    func( b );
};

int main() 
{
    A().foo( B() );

    return 0;
}

The program output is

Hello A!

A more simpler way to define a functional object is to use lambda expressions.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335