In Java, when I need a callback function, I have to implement an anonymous class. Inside the anonymous class, I can access the outside variables if they're final
.
Now I'm doing the same thing in C++. I understand that C++ lambda works better but sometimes I need to pass in many functions where with anonymous classes, I only need to pass in one instance.
I tried the following example. It works with GCC 4.3.4.
class IA {
public:
virtual int f(int x) = 0;
};
int main() {
class : public IA {
int f(int x) { return x + 1; }
} a;
doFancyWork(&a);
return 0;
}
Is it possible to capture the outside variables like this?
int main() {
int y = 100; // mark y as final if possible
class : public IA {
int f(int x) { return x + y; }
} a;
return 0;
}
UPDATE:
The second example won't compile. The errors are here,
prog.cpp: In member function ‘virtual int main()::<anonymous class>::f(int)’:
prog.cpp:9: error: use of ‘auto’ variable from containing function
prog.cpp:7: error: ‘int y’ declared here
prog.cpp: In function ‘int main()’:
prog.cpp:7: warning: unused variable ‘y’
UPDATE:
I just realized a few more problems in doing this:
I think I have to move away from anonymous classes.
There is no way to automatically capture those variables, but you can use an alternative approach. This is if you want to capture by reference:
int main() {
int y = 100; // mark y as final if possible
class IB : public IA {
public:
IB(int& y) : _y(y) {}
int f(int x) { return x + _y; }
private:
int& _y;
} a (y);
return 0;
}
If you want to capture by value, just change int&
into int
.
Anyway, you may consider using a tuple of lambdas as a "multi-callback" object if that is what bothers you about individual lambdas. You would still have everything packed in one object and capturing would be done for free.
Just as an example:
auto callbacks = make_tuple(
[] (int x) { cout << x << endl; },
[&] () { cout << y << endl; }, // y is captured by reference
[=] (int x) { cout << x + y << endl; }, // y is captured by value
// other lambdas here, if you want...
);