Search code examples
c++c++11lambdafriendstd-function

std::function as a friend of the class


Consider this code :

#include <functional>

class A{
public:
    std::function<void(A* obj)> todo;
    void doWork(){
        if(todo)
            todo(this);
    }

private:
    void dummy(){}
    friend void todo(); // not working
};

int main(int argc, char *argv[])
{
    A tmp;
    tmp.todo = [](A *obj){
        obj->dummy();
    };
    tmp.doWork();

    return 0;
}

Of course, we can't build this code because 'A::dummy': cannot access private member declared in class 'A'. I think it is impossible, but is there a way of accessing to the private members of class A from the lambda declaration ??


Solution

  • friend void todo(); // not working
    

    Yes, it's not working. This declares that the friend function is some function called "todo".

    This is not the same thing as a class member of the same name. Friends are functions (or classes), and not class members.

    The fundamental issue you are facing here is a combination of two fundamental C++ aspects:

    1. std::function<something> is a concrete, discrete class of its own.

    2. Each lambda is an anonymous class, and all lambda are discrete, different anonymous classes.

    You could declare something like:

    friend class std::function<void(A* obj)>;
    

    But that's not going to accomplish anything productive. This will allow the std::function template itself to access private members of this class. So, if something in the internal implementation of your C++ library's std::function template needs to access a private class member, it can now do that. But, of course, there's nothing in std::function itself that has any awareness of your class.

    And since each lambda itself is a discrete anonymous class, this has no effect on any lambda. std::function itself is a concrete class of its own, which effects type erasure, for these anonymous lambdas.

    In short, this cannot be done in C++. What you are really want to have is make a specific anonymous lambda class a friend of this class. But there is no such syntax in C++. You must come up with some other alternate strategy of giving your lambdas access to your class's private members.