Заменить лямбда-функцию на полиморфную функцию-член - PullRequest
5 голосов
/ 21 сентября 2019

У меня есть следующий член в полиморфном классе Parent, и я ищу способ заменить foo на какой-то виртуальный член bar:

void Parent::myFunc() {
    // lots of variables
    // complicated calculations

    while (/* loop condition */) {
        // more variables and calculations

        auto foo = [&](int n) {/* ... */};

        foo(42);
        // want to replace with virtual
        // bar(42);
    }
}

Я проблемаИмеется в том, что foo захватывает все, и я не знаю, как правильно предоставить bar такой же доступ.

  1. Передача всего в bar в качестве параметров приведет к большому списку параметров, и это не выглядит элегантным решением
  2. Я также могу превратить локальные переменные в myFunc()в члены Parent, но это излишне увеличит время жизни этих переменных, особенно для переменных цикла.

1 Ответ

2 голосов
/ 22 сентября 2019

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

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

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

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

...