Javascript стиль закрытия в C ++ - PullRequest
2 голосов
/ 31 января 2020

Во-первых, извинения за то, что этот заголовок, вероятно, заставил некоторых из вас, ребят из c ++, вас немного поднять. Однако позвольте мне объяснить, что я пытаюсь выполнить sh.

Я передаю лямбду (назовем ее funcA) в качестве параметра другой функции (назовите ее funcB). Есть ли способ для меня объявить переменные в funcB и получить к ним доступ в рамках funcA, не передавая их в funcA в качестве параметров, подобно тому, как работают javascript замыкания?

Простой пример (который явно не работает) будет выглядеть следующим образом:

void funcB(std::function<void()> funcA) {
    int testInt = 44;
    funcA();
}

int main() {
    funcB([&]() {
        std::cout << testInt; // undefined identifier
    });

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 31 января 2020

Похоже, что я неправильно понял, что именно происходило в javascript, что позволяло этому поведению происходить. После более глубокого изучения я вижу, что единственные переменные времени доступны в замыканиях, когда определение переменной находится в пределах родительской области определения замыкания как таковое:

var funcB = function(funcA){
    funcA();
};

(function(){

  var firstVar = 1;
  var secondVar = 2;

  funcB(function(){
    alert(firstVar + secondVar);
  });

})();

Такое же поведение может быть достигнуто с помощью лямбда-захват (как предложено пользователем @Marek R в комментариях к вопросу) в C ++ следующим образом:

void funcB(std::function<void()> funcA) {
    funcA();
}

int main() {

    int firstVar = 1;
    int secondVar = 2;

    funcB([&]() {

        std::cout << firstVar + secondVar;

    });

    std::cin.get();
    return 0;
}

Поэтому мой первоначальный вопрос возник из-за незнания того, чего я не знал. Чтобы достичь того, чего я на самом деле хочу, мне нужно будет передать параметры моей лямбде или реализовать другой шаблон проектирования.

0 голосов
/ 31 января 2020

Что ж, в этом конкретном примере идиоматический способ c будет использовать возвращаемое значение:

void funcB(std::function<int()> funcA) {
    int testInt = funcA();
}

int main() {
    funcB([&]() {
        int testInt = 44;
        std::cout >> testInt;
        return testInt;
    });

    return 0;
}

Можно использовать выходной параметр, но менее обычно:

void funcB(std::function<void(int&)> funcA) {
    int testInt = 44;
    funcA(testInt);
}

int main() {
    funcB([&](int& testInt) {
        std::cout >> testInt;
    });

    return 0;
}
...