I have a lambda that I need to convert into a callable object so that I can specialize the call operator. My impression has always been that a lambda with an void(auto)
signature was equivalent to a callable struct roughly like this:
struct callable {
Foo & capture;
template< typename T >
void operator()( T arg ) { /* ... */ }
}
However, a lambda can access private and protected members when it is declared within a member function.
Here's a simplified example:
#include <iostream>
using namespace std;
class A {
protected:
void a() { cout << "YES" << endl; }
};
class B : public A {
public:
void call1();
void call2();
};
struct callable {
B * mB;
void operator()() {
// This does not compile: 'void A::a()' is protected within this context
// mB->a();
}
};
void B::call1() {
// but then how does this access a() ?!
[&]() { a(); }();
}
void B::call2() {
callable c{ this };
c();
}
int main()
{
B b;
b.call1();
b.call2();
}
Is there any way to emulate that behavior in a callable struct, without declaring it in the header and making it a friend class? That seems problematic because I'm going to have a lot of different callables. I'm also just curious about it, because I was under the impression that lambdas were functionally identical to declaring a struct with a call operator.
Access rights of a lambda capturing this seems to say that the lambda has the same access as a local class. But in my case, I need to emulate a generic lambda, and local classes can't have template member functions.