Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ non-copyable lambda behaves copyable?

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.

like image 434
Andreas Loanjoe Avatar asked Apr 12 '19 16:04

Andreas Loanjoe


1 Answers

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.

like image 139
cpplearner Avatar answered Nov 02 '22 18:11

cpplearner