I had the following code:
#include <iostream>
class Foo
{public:
Foo() {}
int a;
};
int main()
{
Foo foo;
auto lambda = [=]() mutable { std::cout << foo.a; };
}
And things were working fine, until I needed to add a copy constructor to my Foo class:
Foo(Foo& t) {}
And it wouldn't compile anymore, giving the message:
class 'Foo': no copy constructor available or copy constructor is declared 'explicit'
I've made the lambda mutable because I didn't want capture a const Foo, but what I think is happening is that the lambda can't be copied. Another compiler had a more useful error message:
error: use of deleted function ‘main()::< lambda()>::< lambda>(main()::< lambda()>&&)’
and:
main()::< lambda()>::< lambda>(main()::< lambda()>&&)’ is implicitly deleted because the default definition would be ill-formed:
But I don't really understand this. Is that implicitly deleted function the move constructor of the lambda? I can't understand why just adding a copy constructor to the captured class (not the lambda) makes this happen.
This is what I picture lambda/functor as looking like:
class lambda
{public:
Foo foo; // <---- My captured variable/class
void operator()(){ std::cout << foo.a; }
}
So then a copy of one of these lambdas to another involves calling Foo's assignment operator or copy constructor? I don't understand how just Foo having a copy constructor makes this fail or what is "ill-formed". The other thing I noticed is that there's no problem when the lambda captures by reference [&].
Edit: It doesn't compile on this compiler:
https://www.jdoodle.com/online-compiler-c++/
I'm on Visual Studio and it wouldn't compile. However when I made a much smaller example it would compiler, but still underline the error. In my larger project it doesn't compile.
MSVCandclang-cl(using C++17 standard). What compiler and standard are you using? - Adrian Mole