У меня был следующий код:
#include <iostream>
class Foo
{public:
Foo() {}
int a;
};
int main()
{
Foo foo;
auto lambda = [=]() mutable { std::cout << foo.a; };
}
И все работало нормально, пока мне не нужно было добавить конструктор копирования в мой класс Foo:
Foo(Foo& t) {}
И это не будет больше не компилируется, выдавая сообщение:
класс 'Foo': конструктор копирования недоступен или конструктор копирования объявлен 'явным'
Я сделал лямбду мутабельной потому что я не хотел захватывать const Foo, но я думаю, что происходит то, что лямбда не может быть скопирована. У другого компилятора было более полезное сообщение об ошибке:
ошибка: использование удаленной функции 'main () :: :: (main () :: &&) '
и:
main () :: :: (main () :: &&) 'неявно удаляется, потому что определение по умолчанию будет неверно сформировано:
Но я не совсем понимаю это. Является ли эта неявно удаленная функция конструктором перемещения лямбды? Я не могу понять, почему простое добавление конструктора копирования в захваченный класс (а не лямбда) делает это возможным.
Вот как я представляю лямбду / функтор следующим образом:
class lambda
{public:
Foo foo; // <---- My captured variable/class
void operator()(){ std::cout << foo.a; }
}
Итак, когда копирование одной из этих лямбд в другую включает вызов оператора присваивания Foo или конструктора копирования? Я не понимаю, как просто Foo, имеющий конструктор копирования, делает этот сбой или что "плохо сформировано". Еще одна вещь, которую я заметил, состоит в том, что нет проблем, когда лямбда захватывает по ссылке [&].
Редактировать: Он не компилируется на этом компиляторе:
https://www.jdoodle.com/online-compiler-c++/
Я в Visual Studio, и он не будет компилироваться. Однако, когда я сделал гораздо меньший пример, он бы компилировал, но все же подчеркнул ошибку. В моем более крупном проекте он не компилируется.