How to provide access to an object with a protected object, for example lambda in C ++?

I have a lambda that I need to convert to a callable object so that I can specialize the call statement. My impression has always been that a signed lambda is void(auto)equivalent to a called structure like this:

struct callable {
    Foo & capture;

    template< typename T >
    void operator()( T arg ) { /* ... */ }
}

However, lambda can access private and protected members when declared inside a member function.

Here is 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 a way to imitate this behavior in the called structure without declaring it in the header and making it a class of friends? This seems problematic because I will have many different challenges. I am also just curious because I got the impression that lambdas are functionally identical to declaring a structure using a call statement.

, , , , . , .

+4
2

this &B::a

struct callable {
    B* mB;
    void (A::*m)();

    void operator()() const {
        (mB->*m)();
    }
};

void B::call2() {
    callable c{ this, &B::a };
    c();
}

+2

struct callable a friend B . , :

class B : public A {
  // ...
  friend struct callable;
}

// ERROR: callable isn't visible here:
// callable *foo;

, , :

class B : public A {
  // ...
  template<int> friend struct callable;
};

// In implementation:
template<>
struct callable<0> { /* ... */ };
template<>
struct callable<1> { /* ... */ };
0

Source: https://habr.com/ru/post/1685494/


All Articles