std :: unordered_map <T, std :: unique_ptr <U >> kopierbar? GCC-Fehler?

g++ --version ergibt:

g++.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Programm

#include <memory>
#include <type_traits>
#include <unordered_map>

static_assert(!std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>>>::value,"Copyable");

int main () {   }

Ergebnis der Zusammenstellung:

.\unorderedmapcopyable.cpp:5:1: error: static assertion failed: Copyable
 static_assert(!std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>>>::value,"Copyable");
 ^

Relevant standardese:

uf Behältern, die kopierbar si

Für die AnweisungenX u(a) undX u=a um gültig zu sein, für einige ContainertypenX, welches den Typ @ enthäT, wohera ist ein Wert vom TypX:

Erfordert: T istCopyInsertableinX

§23.2.1 [container.requirements.general]

Mein Verständnis davon: WennT (in unserem Fallstd::pair<const int,std::unique_ptr<int>>) ist nichtCopyInsertableinX (in unserem Fallstd::unordered_map<int,std::unique_ptr<int>>), dannX u(a) undX u=a sind nicht wohlgeformt.

AufCopyInsertable

T istCopyInsertableinX bedeutet, dass zusätzlich zuT SeinMoveInsertableinX, der folgende Ausdruck ist wohlgeformt:

allocator_traits<A>::construct(m, p, v)

und seine Auswertung bewirkt, dass die folgende Nachbedingung gilt: Der Wert vonv ist unverändert und entspricht*p.

Mein Verständnis davon: std::pair<const int,std::unique_ptr<int>> ist nichtCopyInsertable, aufgrund der Tatsachestd::unique_ptr<int> kann nicht kopiert werden:

Jedes Objekt eines TypsU instanziiert aus demunique_ptrie in diesem Unterabschnitt [...] angegebene @ -Vorlage ist nichtCopyConstructible NochCopyAssignable.

§20.8.1 [unique.ptr]

Und aufgrund der Tatsache, dass der Kopierkonstruktor vonstd::pair<const int,std::unique_ptr<int>> ist voreingestellt:

pair(const pair&) = default;

§20.3.2 [pairs.pair]

nd aufgrund der Tatsache, dassstd::pair<const int,std::unique_ptr<int>> hat ein Mitglied vom Typstd::unique_ptr<int>:

template <class T1, class T2> struct pair {

[...]

T2 second;

§20.3.2 [pairs.pair]

Und aufgrund der Tatsache, dass standardmäßige Kopierkonstruktoren gelöscht werden, wenn nicht alle Mitglieder eines Typs @ sinCopyConstructible:

Ein voreingestellter Copy / Move-Konstruktor für eine KlasseX ist als gelöscht definiert, wenn X hat:

[...]

ein nicht statisches Datenelement des KlassentypsM (oder ein Array davon), das nicht kopiert / verschoben werden kann, da die Überladungsauflösung auf @ angewendet wiMer entsprechende Konstruktor von @ führt dazu, dass [...] eine Funktion gelöscht wird.

§12.8 [class.copy]

Aufstd::is_copy_constructible

Für einen referenzierbaren TypT, das gleiche Ergebnis wieis_constructible<T,const T&>::value, Andernfallsfalse.

§20.10.4.3 [meta.unary.prop]

Mein Verständnis / Lesen davon: std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>> ist das gleiche wiestd::is_constructible<std::unordered_map<int,std::unique_ptr<int>,std::unordered_map<int,std::unique_ptr<int> &>.

Aufstd::is_constructible

Gab den folgenden Funktionsprototyp:

template <class T> add_rvalue_reference_t<T> create() noexcept;

die Prädikatbedingung für eine Template-Spezialisierungis_constructible<T, Args...> muss genau dann erfüllt sein, wenn die folgende Variablendefinition für eine erfundene Variable gut formuliert wäret:

T t(create<Args>()...);

§20.10.4.3 [meta.unary.prop]

Mein Verständnis davon: std::is_constructible<std::unordered_map<int,std::unique_ptr<int>>,std::unordered_map<int,std::unique_ptr<int> &> sollte @ sestd::false_type, nichtstd::true_type, schon seitX u(a) ist nicht wohlgeformt.

Meine Frag

Sollte der obige Code akzeptiert werden? Handelt es sich um einen GCC / libstdc ++ - Fehler, oder fehlt mir etwas im Standard?

Ich habe derzeit keinen Zugriff auf Clang oder MSVC ++, sonst würde ich sie testen.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage