http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55043
--- Comment #17 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2012-10-24 17:48:07 UTC --- (In reply to comment #15) > > 1) It will prevent the incomplete type support > > Ouch... but not required by the standard. I agree, but I consider that as a high price. > > 2) The implementation changes are not small (my guess) > > Apart from the changes to allocator_traits and defining CopyInsertable etc. > (which I think isn't so hard, I can do that tonight) IIUC it would require > changing every container so that e.g. > > vector<T,A>::vector(const vector&) > > becomes > > template<typename U> > vector<T,A>::vector(const vector<U,A>&) > > with constraints is_same<T,U> and CopyInsertable<A,T>, because we can't > constrain that constructor if it's not a template > > Is that even allowed under the as-if rule? I don't think that this works. I can elaborate what I had in my mind when comparing with optional, but I think this is not needed to solve the issue and would lengthen here the discussion. Looking at the concrete problem here I think the only thing that is needed is a conditional noexcept for all containers move constructors (which is presumably a border-case for the allowed extensions but to me an acceptable one. I tend to suggest to open an LWG issue for this). Now I'm reading below that the move constructor always seems to need to allocate memory, is that really true? IMO that is the actual problem here. > Is there some other way to make examples like this compile? > > #include <vector> > > struct M > { > M() = default; > M(M&&) = default; > M& operator=(M&&) = default; > }; > > typedef std::vector<M> S; > > static_assert( !std::is_copy_constructible<S>::value, > "not CopyConstructible" ); This is possible with my more-constraining model in mind that would really enforce that vectors value type is a complete type during instantiation of vector. I do not suggest to follow this path, but if you really want to do that, here the sketch (I can show you the complete code of my optional implementation that does so, if you want): The basic idea is to ensure that vector becomes conditionally derived from a base-class with a deleted copy-constructor. An empty tagging class suffices, e.g. template<> struct ctor_base<member_policy::move | member_policy::copy> { constexpr ctor_base() noexcept = default; ctor_base(const ctor_base& rhs) noexcept = default; ctor_base(ctor_base&& rhs) noexcept = default; ctor_base& operator=(const ctor_base&) noexcept = default; ctor_base& operator=(ctor_base&&) noexcept = default; }; template<> struct ctor_base<member_policy::move> { constexpr ctor_base() noexcept = default; ctor_base(const ctor_base&) = delete; ctor_base(ctor_base&& rhs) noexcept = default; ctor_base& operator=(const ctor_base&) noexcept = default; ctor_base& operator=(ctor_base&&) noexcept = default; }; The condition for the base class selection is the outcome of std::is_copy_constructible<value_type>. This design has the effect that you can delete-away the effective copy-constructor of the container, if the value type is not copyable.