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 siFü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
istCopyInsertable
inX
§23.2.1 [container.requirements.general]
Mein Verständnis davon: WennT
(in unserem Fallstd::pair<const int,std::unique_ptr<int>>
) ist nichtCopyInsertable
inX
(in unserem Fallstd::unordered_map<int,std::unique_ptr<int>>
), dannX u(a)
undX u=a
sind nicht wohlgeformt.
CopyInsertable
T
istCopyInsertable
inX
bedeutet, dass zusätzlich zuT
SeinMoveInsertable
inX
, 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_ptr
ie 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 wiM
er 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> &>
.
std::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.
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.