Search code examples
c++lambdafriend

How to make a lambda function friend of a class?


I was trying to make a class that takes as argument in the constructor a lambda function, and I want this function to be friend with the class. The code for the class looks like this:

using func = std::function<void(void)>;    

class foo
{
public:
    foo(func f)
    {
        this->f = f;
    }

    func f;
private:
    int value_I_want_to_modify; //an int I want to change from the function I've passed in the constructor
}

And in the main() I would write something like this:

int main()
{
    //this will give an error because I cannot access private members from outside class
    foo v
    {
        [&v](void) { v.value_I_want_to_modify = 0 };
    }
}

Now I would like the function to be friend with the class but I can't find a way to do it.


Solution

  • How to make a lambda function friend of a class?

    You cannot. It's a catch-22 problem.


    If you define the lambda function before defining the class, you can't access the member variable of the class.

    using func = std::function<void(void)>;    
    
    class foo;
    
    // Trying to define the lambda function before the class.
    // Can't use f.value_I_want_to_modify since foo is not defined yet.
    auto lambda_function = [](foo& f) { f.value_I_want_to_modify = 0;}
    
    class foo
    {
       public:
          foo(func f)
          {
             this->f = f;
          }
    
          func f;
       private:
          int value_I_want_to_modify;
    };
    
    int main()
    {
        foo v{lambda_function};
    }
    

    If you define the lambda function after defining the class, you can't make the lambda function a friend of the class.

    using func = std::function<void(void)>;
    
    class foo
    {
       public:
          foo(func f)
          {
             this->f = f;
          }
    
          func f;
       private:
          int value_I_want_to_modify;
    };
    
    int main()
    {
       foo f
       {
          // Can't make the lambda function a friend of foo
          // since it cannot be declared before the class definition.
          [&f](void) { f.value_I_want_to_modify = 0;}
       }
    }
    

    The easiest work around is to modify the lambda function to accept an int& as argument and modify its value.

    #include <functional>
    
    using func = std::function<void(int&)>;
    
    class foo
    {
       public:
          foo(func f)
          {
             this->f = f;
             this->f(value_I_want_to_modify);
          }
    
       private:
    
          func f;
          int value_I_want_to_modify;
    };
    
    int main()
    {
       foo v{ [](int& out) { out = 0;} };
    }