2013-04-06 8 views
9

Zu meiner Überraschung habe ich einen Fehler erhalten, wenn ich std::vector::get_allocator() mit einem nicht kopierbaren Zuordner verwenden wollte. Warum gibt std::vector::get_allocator() by-value und nicht by-reference zurück?Warum gibt std :: vector :: get_allocator() by-value zurück?

template<typename T> 
class nc_allocator { 
public: 
    using value_type = T; 

    nc_allocator(nc_allocator const&) = delete; 
    nc_allocator& operator=(nc_allocator const&) = delete; 

    // Other required members. 
}; 

std::vector<int, nc_allocator<int>> v; 
// boom: use of deleted function 
//   'nc_allocator<T>::nc_allocator(const nc_allocator<T>&) [with T = int]' 
v.get_allocator(); 
+2

Ich vermute, dass Instanzen von Allokatoren wie Griffe behandelt werden sollen. Der Beweis dafür ist, dass zwei Zuordner nur als gleich angesehen werden, wenn man die Objekte des anderen löschen kann. –

Antwort

7

ich einen Fehler bekam, als std::vector::get_allocator() mit einem nicht-kopierbaren allocator zu verwenden versuchen.

Der Standard verbietet es Ihnen, dies zu tun. Die Zuteileranforderungen in 17.6.3.5 geben an, dass ein Zuordner kopierbar sein soll.

X a1(a);   Shall not exit via an exception. 
       post: a1 == a 
X a1(move(a)); Shall not exit via an exception. 
       post: a1 equals the prior value 
       of a. 

So als Wert zurückgeben ist ein richtiger Weg, um eine allocator der Rückkehr über die allocator Anforderungen der Norm definiert.

Ich bin mir nicht sicher warum Dies ist eine Voraussetzung, aber wenn nicht kopierbare Allokatoren erlaubt wären, würde die leere Basisoptimierung nicht mehr funktionieren.

+0

Streng genommen sagt das nur, dass eine Kopieroperation nicht über eine Ausnahme beendet werden darf; es sagt nicht, dass es möglich sein muss. –

+2

Es besagt, dass dieser Ausdruck gültig sein muss und dieser Ausdruck ist genau derselbe wie für CopyConstructible-Typen. Es ist noch stärker, da das Kopieren keine Ausnahme auslösen darf. – ipc

+0

Es ist nicht stärker als der wortwörtliche Text "das Mitglied get_allocator() gibt eine Kopie zurück" –

1

Der Standard schreibt vor, so einfach:

[C++11: 23.2.1/7]:[..] In allen Behältertypen in dieser Klausel definiert, das Mitglied get_allocator() eine Kopie des Zuordner kehrt verwendet, den Behälter zu konstruieren, oder , wenn das allocator ersetzt wurde, wird eine Kopie des letzten Ersatz [..]

ich vermute @ Vaughns richtig in seine Hypothese, dass Verteilern u sein sollen sed als "Griffe".

Von sehr lose Analogie, würden Sie jemals einen nicht kopierbaren Funktor für die Verwendung mit Standard-Algorithmen schreiben?

+4

Aber warum sagt der Standard so? –

+0

@Zoidberg: Weil jemand entschieden hat, dass es muss. Der Versuch, zu erklären, warum X mit der Y-Eigenschaft erstellt wurde, ist sowohl nicht konstruktiv als auch nicht Thema bei Stack Overflow. –

+0

Wie macht man diesen Teil des Standards "wenn dieser Allokator ersetzt wurde"? –

Verwandte Themen