Mit move-Semantik mit std::pair oder std::tuple
Angenommen, Sie möchten, um die Vorteile der move-Semantik, aber eine Ihrer beweglichen Klassen braucht, um Teil einer std::pair
. Der Zweck wäre, zu erstellen, die eine Funktion zurückgibt, die ein std::pair
behandelt werden kann wie eine rvalue und weitergeleitet werden, zusammen.
Aber ich kann nicht sehen, wie dies getan werden kann, es sei denn, eine interne änderung std::pair
selbst gemacht wird, um Kenntnis von move-Semantik.
Betrachten Sie den folgenden code:
struct Foo
{
Foo() { }
Foo(Foo&& f) { }
private:
Foo(const Foo& f) { } //do not allow copying
};
int main()
{
Foo f;
std::pair<Foo, int> res = std::make_pair(f, 10); //fails due to private copy constructor
}
Das problem ist, dass std::make_pair
sowie die std::pair
Konstruktor selbst, nimmt zwei Objekte und versucht, interne Kopien von Ihnen. Dies bewirkt, dass es zu versuchen, und ruft den copy-Konstruktor. Aber in meinem Beispiel möchte ich in der Lage sein, um bewegen das neue paar in res
, und sicherzustellen, dass keine Kopien gemacht werden. Ich würde denken, das wäre nicht möglich, es sei denn std::pair
selbst hatte den folgenden Konstruktor definiert intern:
pair(T1&& t1, T2&& t2) : first(std::move(t1)), second(std::move(t2))
Aber es funktioniert nicht, zumindest nicht auf den compiler, die ich benutze (gcc 4.3.2). Kann es sein, dass mein compiler ist einfach veraltet, und neuere Versionen in der Tat wird diese bewegen sich-bewusst-Konstruktor. Aber mein Verständnis von move-Semantik ist etwas unausgereift im moment, so bin ich nicht sicher, ob ich einfach etwas Blick hier. Also, das ist, was ich versuche zu erreichen, ohne tatsächlich reimplementing std::pair
? Oder ist mein compiler nur veraltet?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist das nicht der
std::pair
Konstruktor, der aufgerufen wird, wenn. Diestd::pair
move-Konstruktor aufgerufen werden, und die move-Konstruktor sollte genau das tun, was Sie erwarten (N3126 20.3.5.2/6):Aber dein Beispiel sollte scheitern, weil in
std::make_pair(f, 10);
,f
ist ein lvalue und muss explizitmove
d, sonst ist es kopiert. Folgendes sollte funktionieren:GCC 4.3.2 nicht haben, müssen eine vollständige Umsetzung. paar (und Tupel) haben move-Konstruktoren:
(Aus [Paare.paar] in n3126)