2014-12-13 6 views
7

Der C++ 11-Standard (oder mindestens this working draft) erfordert, dass Klassen, die das Allocator-Konzept implementieren, Kopierkonstruktoren bereitstellen.Warum die Anforderung, dass benutzerdefinierte Zuordner kopierbar sind?

Dies machte Sinn, wenn alle Zuordner zustandslos sein mussten, aber wenn der Status in einer Zuweisungsklasse erlaubt ist, ist die Bereitstellung eines Kopierkonstruktors möglicherweise nicht wünschenswert. Wenn der Zuordner beispielsweise eine Art Plattenzuordnungssystem oder Speicherpool implementiert, in dem eine interne Freelist verwaltet wird. Es scheint mir, dass ein solcher Allokator immer verschoben werden sollte, nie kopiert werden. Tatsächlich würde das Kopieren eines neuen Speichers und das vollständige Reproduzieren des internen Zustands des ursprünglichen Zuordners erforderlich sein, einschließlich aller freien Speicherblöcke, Freilisten usw. (Oder bedeutet das "Kopieren" eines Allocator einfach die Rückkehr Allocator(), dh das Zurückgeben eines neuen Standards Konstruktionen bilden allocator?)

Eigentlich Kopieren ein state-ful allocator scheint völlig unnötig zu sein, denn soweit ich sehen kann, in der Praxis gibt es keinen wirklichen gemeinsamen anwendungs~~POS=TRUNC für ein allocator Kopie-Konstruktion. Nein Container kopiert tatsächlich einen Zuordner - C++ 11 Container rufen stattdessen Allocator::select_on_container_copy_construction innerhalb des Containerkopierkonstruktors auf, der normalerweise nur Allocator() zurückgibt. Dann wird der Container normalerweise Element für Element aus dem anderen Container kopieren, wahrscheinlich indem einfach Container::insert aufgerufen wird.

Natürlich eine optimierte Behälter Implementierung könnte etwas komplexer mit internem Wissen über die Behälterstruktur, aber noch niemand wird zu other.get_allocator() copy-Konstrukt - die Container werden nur other.get_allocator().select_on_container_copy_construction() rufen einen Standard konstruierte allocator zu bekommen.

Warum haben wir also die Anforderung, dass ein Allocator selbst muss kopierbar sein? Sollte der Bau nicht ausreichen?


Hinweis: Um klar zu sein, diese Frage ist nicht ein Duplikat why does allocator in c++ need a copy constructor?. Diese Frage fragt speziell nach std::allocator (die zustandslos ist), während ich nach benutzerdefinierten Zuordnern frage, die das Allocator Konzept implementieren.

+1

Nehmen die allocator-bewussten Containerkonstruktoren ihre Allokatoren nicht mit const ref? Außerdem ist 'get_allocator()' so definiert, dass es eine Kopie seit C++ 11 zurückgibt, so dass eine Nur-Bewegung-Funktion nicht funktionieren würde, und das Ändern kann durchaus eine brechende Änderung sein. –

Antwort

0

Re Anspruch

Kein Container tatsächlich kopiert ein allocator

das so sein kann (ich habe nicht getestet) und std::string kann als nicht Container angesehen werden aber immer noch:

#include <string> 
#include <iostream> 
#include <memory>  // std::allocator 

template< class Type > 
struct Alloc 
    : std::allocator<Type> 
{ 
    using Base = std::allocator<Type>; 

    template< class Other > 
    struct rebind 
    { 
     using other = Alloc<Other>; 
    }; 

    Alloc() {} 

    Alloc(Alloc<Type> const& other) 
     : Base(other) 
    { std::clog << "Alloc::<copy>\n"; } 

    template<class Other> 
    Alloc(Alloc<Other> const& other) 
     : Base(other) 
    { std::clog << "Alloc::<generic-copy>\n"; } 
}; 

auto main() -> int 
{ 
    using namespace std; 
    basic_string< char, char_traits<char>, Alloc<char> > a = "A", b = "B"; 
    a = b; 
} 

Ausgabe w iit Visual C++:

 
Alloc::<copy> 
Alloc::<copy> 

Mit g ++ ist die Anzahl der Zuordnerkopiervorgänge höher.

+0

libC++ kopiert überhaupt nicht.Außerdem denke ich, dass Sie Move-Konstruktoren hinzufügen sollten, da die OP behauptet * "Sollte die Konstruktion nicht ausreichen?" * - dies ändert die Ausgabe weder für VS2013 noch für libstdC++, IMHO überraschend. – dyp

Verwandte Themen