Suppose we have a non-copyable type X:
struct X
{
X(X&&) = default;
X(const X&) = delete;
}
Then, naturally, we cannot copy a container having X as value type:
std::set<X> v;
std::set<X> v2{v} // error
My question is, whether the expression that involves such a copy is well-formed? For instance, the following expression compiles:
sizeof( std::set<X>{v} )
I am asking since I run into the following problem:
std::cout << std::is_copy_constructible_v< X >;
std::cout << std::is_copy_constructible_v< std::set<X> >;
Which prints out 01. It's a bit counter-intuitive that std::set<X> is "reported" being copy-constructible when in fact it is not (by means of that its copy constructor cannot be called).
That comes from a problem you have, when your container shall support incomplete types. You cannot do both
If you support incomplete types, you cannot check in the declaration of the copy constructor if that type is copyable (since it could be incomplete at that point). So, you can always instantiate the copy constructor. But if you do, that will fail in evaluated contextes.
There is a good article on this: https://quuxplusone.github.io/blog/2020/02/05/vector-is-copyable-except-when-its-not/