Why is an std::vector of noncopyable elements copyable (according to concepts)?

#include<concepts>
#include<vector>

struct nc { nc(const nc&) = delete; };
static_assert(!std::copyable<nc>);  // OK
static_assert(!std::copyable<std::vector<nc>>);  // fails, why?

I have tried this with both gcc 13 and clang 17. Is this a bug in those compilers (or the respective library implementations) or is it really the desired behaviour? Obviously, std::vector<nc> is not std::copyable as the following fails to compile:

std::vector<nc> v;
std::vector<nc> w = v;  // does not compile

>Solution :

You can check out this article: Why does std::is_copy_constructible report that a vector of move-only objects is copy constructible?

The TLDR is is_copy_constructible only checks that there is a copy constructor, not that it is a valid copy constructor. std::vector does have a copy constructor, but it is not a valid one if you try to compile it for this type. But is_copy_constructible doesn’t try that, because the definition of the constructor could be defined elsewhere, and the type-trait cannot go and verify whether or not it is a valid definition.

Leave a Reply