Was ist der Punkt des Konstruktors std :: function mit benutzerdefiniertem Zuordner, aber keine anderen Argumente?

8

Ich spiele mit std :: function und benutzerdefinierten Allokatoren herum, aber es verhält sich nicht so, wie ich es erwartet habe, wenn ich die Funktion nicht mit einem anfänglichen Funktor versehen habe.

Wenn ich dem Konstruktor einen benutzerdefinierten Allocator, aber keinen initialen Funktor zur Verfügung stelle, wird der Allocator niemals verwendet, oder so scheint es.

Das ist mein Code.

%Vor%

Ausgabe:

%Vor%

Also case1: myFunction1 weist wie erwartet den Befehl allocator1 zu.

case2: myFunction2 erhält im Konstruktor allocator2, aber wenn ein Funktor zugewiesen wird, scheint er auf den Standard-std :: allocator zurückgesetzt zu werden, um die Zuweisung vorzunehmen (daher kein Ausdruck über die Zuweisung).

case3: myFunction3 erhält den allocator3 im Konstruktor, aber wenn er von myFunction1 zugewiesen wird, erfolgt die Zuweisung mithilfe des Zuweisungsfunktionals von function1, um die Zuweisung vorzunehmen.

Ist das richtiges Verhalten? Insbesondere im Fall 2, warum zurück zur Verwendung von Standard std :: allocator? Wenn ja, was ist der Sinn des leeren Konstruktors, der einen Zuordner verwendet, da der Zuordner niemals verwendet wird.

Ich verwende VS2013 für diesen Code.

Meine Allocator-Klasse ist nur eine minimale Implementierung, die neue verwendet und sich abmeldet, wenn sie

zuweist %Vor%     
David Woo 15.09.2015, 21:32
quelle

1 Antwort

5

std::function 's Allokator-Unterstützung ist ... seltsam.

Die aktuelle Spezifikation für operator=(F&& f) lautet: std::function(std::forward<F>(f)).swap(*this); . Wie Sie sehen können, bedeutet dies, dass der Speicher für f mit dem von std::function standardmäßig verwendeten Wert zugewiesen wird und nicht mit dem zum Erstellen von *this verwendeten Zuordner. Das Verhalten, das Sie beobachten, ist korrekt, aber überraschend.

Da außerdem die Konstruktoren (allocator_arg_t, Allocator) und (allocator_arg_t, Allocator, nullptr_t) noexcept sind, können sie den Zuordner nicht wirklich speichern, selbst wenn sie dies wollten (das Löschen eines Zuweisungselements erfordert möglicherweise eine dynamische Zuweisung). Wie es ist, sind sie im Grunde No-Ops, die vorhanden sind, um das Use-Allocator-Konstruktionsprotokoll zu unterstützen.

LWG hat kürzlich ein Problem zurückgewiesen, das dieses Verhalten ändern würde.

    
T.C. 15.09.2015, 21:48
quelle

Tags und Links