From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8861 invoked by alias); 24 Oct 2012 17:48:27 -0000 Received: (qmail 8761 invoked by uid 48); 24 Oct 2012 17:48:08 -0000 From: "daniel.kruegler at googlemail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/55043] [4.7/4.8 Regression] issue with nesting unordered_map containing unique_ptr into vector Date: Wed, 24 Oct 2012 17:48:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: daniel.kruegler at googlemail dot com X-Bugzilla-Status: ASSIGNED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: redi at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-10/txt/msg02226.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D55043 --- Comment #17 from Daniel Kr=C3=BCgler 2012-10-24 17:48:07 UTC --- (In reply to comment #15) > > 1) It will prevent the incomplete type support >=20 > 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) >=20 > Apart from the changes to allocator_traits and defining CopyInsertable et= c. > (which I think isn't so hard, I can do that tonight) IIUC it would require > changing every container so that e.g. >=20 > vector::vector(const vector&) >=20 > becomes >=20 > template > vector::vector(const vector&) >=20 > with constraints is_same and CopyInsertable, because we can't > constrain that constructor if it's not a template >=20 > 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 all= owed extensions but to me an acceptable one. I tend to suggest to open an LWG is= sue 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 her= e. > Is there some other way to make examples like this compile? >=20 > #include >=20 > struct M > { > M() =3D default; > M(M&&) =3D default; > M& operator=3D(M&&) =3D default; > }; >=20 > typedef std::vector S; >=20 > static_assert( !std::is_copy_constructible::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 { constexpr ctor_base() noexcept =3D default; ctor_base(const ctor_base& rhs) noexcept =3D default; ctor_base(ctor_base&& rhs) noexcept =3D default; ctor_base& operator=3D(const ctor_base&) noexcept =3D default; ctor_base& operator=3D(ctor_base&&) noexcept =3D default; }; template<> struct ctor_base { constexpr ctor_base() noexcept =3D default; ctor_base(const ctor_base&) =3D delete; ctor_base(ctor_base&& rhs) noexcept =3D default; ctor_base& operator=3D(const ctor_base&) noexcept =3D default; ctor_base& operator=3D(ctor_base&&) noexcept =3D default; }; The condition for the base class selection is the outcome of std::is_copy_constructible. This design has the effect that you= can delete-away the effective copy-constructor of the container, if the value t= ype is not copyable.