Why does the following code compile?
#include <memory>
#include <vector>
int main()
{
std::vector<std::unique_ptr<int>> uncopyableStuff;
for(int i = 0; i < 5; ++i)
uncopyableStuff.emplace_back(std::make_unique<int>(i));
auto lambda = [uncopyableStuff = std::move(uncopyableStuff)](){};
static_assert(std::is_copy_constructible<decltype(lambda)>::value);
}
It seems to me that lambda is uncopyable, because when I try to copy it like:
auto copy = lambda;
This gives me a compile error (as I would expect). Is there some exception for lambda's and copy constructability traits?
See link for godbolt example: https://godbolt.org/z/GByclH
EDIT:
What is the correct way to find out whether a lambda will compile when attempted to copy. I geuss I'm not interested in the theoretical copy constructibility of a given callable, but a detection of successful copy construction. It still seems very strange to me that the vector copy constructor is defined in this way.
Is there some exception for lambda's and copy constructability traits?
No. If you test std::is_copy_constructible<std::vector<std::unique_ptr<int>>>::value
you will find that it's also true.
The reason is that std::vector
has an accessible and non-deleted copy constructor even if the element type is noncopyable. If the copy constructor is instantiated, it will fail to compile, but that's outside the immediate context, and thus cannot be detected by the std::is_copy_constructible
trait.
It might be tempting to make the copy constructor of std::vector
SFINAE on the copy constructibility of the element type, but I believe it will break a type that stores a vector of the type itself as a member: struct Node { std::vector<Node> children; }
, since in this case, the copy constructibility of Node
and std::vector<Node>
would be mutual dependent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With