Вызов закрытой функции в лямбде вне класса - PullRequest
0 голосов
/ 04 мая 2018

В моем текущем проекте я пытаюсь передать приватную функцию-член в качестве параметра другой функции. В моем коде другая функция является функцией-членом другого класса, но для простоты здесь это свободная функция.

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
};

Теперь изнутри run Я хочу поместить my_func в outside_function в качестве аргумента. Поскольку подпись run не соответствует требованиям для параметра, я не могу просто передать ее. Использование шаблона адаптера было моей первой попыткой, когда мне напомнили, что функции-члены неявно принимают указатель this в качестве первого аргумента. Этот ответ предполагает использование лямбда-выражения, что я и сделал.

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

Почему это работает? С моей точки зрения, outside_function не имеет доступа к my_func. Почему я не должен сначала сделать публичным my_func? Это то, что делает компилятор, или какое-то правило C ++, которого я не знаю?

Кроме того, есть ли какие-то уловки в этом подходе, которые могут нарушить мой код?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

outside_function никогда не обращается к члену (он знает только тип параметра func и не может заботиться о том, как он определен) - делает только лямбда-функция.

Поскольку вы определяете лямбда-функцию внутри MyClass, вы можете получить доступ ко всем частным именам внутри нее.

outside_function вызывает предоставленную функцию, но если вам не разрешено вызывать функцию, использующую какие-либо закрытые члены, вы не сможете многое сделать.

0 голосов
/ 04 мая 2018

private спецификатор доступа только ограничивает объект имя , чтобы быть видимым (его нельзя найти) за пределами класса. Сам объект похож на любой другой член.

[class.access]/1

Членом класса может быть

(1.1) частный; то есть его имя может использоваться только членами и друзьями класса, в котором оно объявлено.

(1,2) защищено; то есть его имя может использоваться только членами и друзьями класса, в котором он объявлен, классами, производными от этого класса, и их друзьями (см. [class.protected]).

(1,3) публично; то есть его имя может использоваться где угодно без ограничения доступа.

...