2

In my current project I am trying to pass a private member function as parameter to another function. In my code, the other function is a member function of a different class, but for keeping it simple, here it is a free function.

void outside_function(std::function<void(int)> func) {
  // do something with func
}


class MyClass {
public:
  void run();

private:
  bool my_func(double); // defined in source file
};

Now, from inside run I want to put my_func into outside_function as argument. Since the signature of run does not fit the requirements for the parameter, I cannot simply pass it. Using the adapter pattern was my first try, which was when I was reminded that member functions implicitly take the this pointer as first argument. This answer suggests using a lambda expression, which is what I did.

void MyClass::run() {
  outside_function([this](int a) -> void {
    double d = static_cast<double>(a);
    this->my_func(d);
  });
}

Why does this work? From my point of understanding, outside_function does not have access to my_func. Why don't I have to make my_func public first? Is it something the compiler does or some C++ rule I don't know?

Additionally, are there any catches to this approach that might break my code?

KorbenDose
  • 797
  • 1
  • 7
  • 23

2 Answers2

6

private access specifier only restrict an object name to be visible (it cannot be looked up) outside the class. The object itself is like any other member.

[class.access]/1

A member of a class can be

(1.1) private; that is, its name can be used only by members and friends of the class in which it is declared.

(1.2) protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see [class.protected]).

(1.3) public; that is, its name can be used anywhere without access restriction.

YSC
  • 38,212
  • 9
  • 96
  • 149
3

outside_function never accesses the member (it only knows the type of the func parameter and can't possibly care about how it's defined) -- only the lambda function does.

Since you're defining the lambda function inside MyClass, you can access all the private names within it.

outside_function calls the provided function, but if you weren't allowed to call a function that uses any private members, you couldn't do much.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • Ok, I get it. My misunderstanding probably was to think of the lambda as something outside of `MyClass`. Thanks! – KorbenDose May 04 '18 at 14:22
  • @KorbenDose lambda expression returns a function object defined in the current scope (governed by capture list). Thus it able access whatever is accessible in that scope. it's equivalent of declaring and creating an instance of class that would be initialized with values or\and references from that scope and got `operator()` defined. – Swift - Friday Pie May 09 '18 at 09:47