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