Andreas Loanjoe
Andreas Loanjoe

Reputation: 2399

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.

Upvotes: 11

Views: 310

Answers (1)

cpplearner
cpplearner

Reputation: 15908

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.

Upvotes: 7

Related Questions