0

I have several methods in my class. I want a lambda in one method to call another method of the class. But I don't want to capture this so that I can limit the scope of what the lambda has access to. Is this possible?

I've tried to capture the method as [&method = Class::my_method] or variations of that but there's something I'm missing.

#include <iostream>

class Hello
{
public:

  double test_lambda(const double in)
  {
      // If I capture `this` instead, then this works fine
      const auto a_lambda = [add_number = this->add_number](const double in)
      {
        return add_number(in);  
      };
      return a_lambda(in);
  }

private:

  double add_number(const double in)
  {
      return in + 2.0;
  }

};

int main()
{
    Hello h;
    std::cout << "Hello World: " << h.test_lambda(4.0); // Expect 6
    return 0;
}

I would hope that I could capture a method like this but I'm not sure if it's possible.

The reason I want to do this based on a coding preference to limit what the lambda has access to. For example, if I wanted the lambda to mutate members of a class, I could do

another_lambda = [this](){
m_value_one = 1.0;
m_value_two = 2.0;
// This has access to other members
}

Or to limit what the lambda can mutate, I can do:

another_lambda = [&value_one = this->m_value_one, &value_two = this->m_value_two](){
value_one = 1.0;
value_two = 2.0;
// This does not have access to other members
}

The post is asking whether the same can be done with class methods, but it seems that it cannot.

10
  • 1
    Capture a method that gets called on what object? What is the this object upon which you want return add_number(in); to operate? Commented Jun 21, 2019 at 22:02
  • 2
    Possible duplicate of Pass a class member function as a function parameter Commented Jun 21, 2019 at 22:11
  • Why, for a 1 line lambda, do you care? Commented Jun 22, 2019 at 2:14
  • @NicolBolas I think I see the problem here, which is why it works if add_number was static Commented Jun 24, 2019 at 15:10
  • @Yakk-AdamNevraumont This was a toy example Commented Jun 24, 2019 at 15:10

1 Answer 1

1

Capturing and using a pointer to member function

A member function isn't a first-class object, and that means that you can't assign in to a variable. The closest thing to this is assigning a pointer to the member function to a variable, but in order to call a pointer to a member function, you need to have a pointer to the original class as well:

#include <iostream>

class Hello
{
   public:
    double test_lambda(double in)
    {
        auto a_lambda = [add_number = &Hello::add_number, this](double in) {
            // This is how we call a pointer to a member function
            return (this->*add_number)(in);
        };
        return a_lambda(in);
    }

   private:
    double add_number(double in) { return in + 2.0; }
};

int main()
{
    Hello h;
    std::cout << "Hello World: " << h.test_lambda(4.0); // Expect 6
    return 0;
}

Simpler solution - capture by reference

We can capture the current class by reference, and this allows you to use add_number without any qualifiers:

#include <iostream>

class Hello
{
   public:
    double test_lambda(double in)
    {
        auto a_lambda = [&](double in) {
            // add_number can be called normally
            return add_number(in);
        };
        return a_lambda(in);
    }

   private:
    double add_number(double in) { return in + 2.0; }
};

int main()
{
    Hello h;
    std::cout << "Hello World: " << h.test_lambda(4.0); // Expect 6
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.