2014-02-19 14 views
16

Die meisten der C++ 11-Code, der std::initializer_list Ich habe gesehen, dauert es nach Wert, aber manchmal wird es von Rvalue Bezug genommen. Gibt es einen guten Grund, dies zu tun?Warum eine std :: initializer_list nach Rvalue-Referenz vs. nach Wert?

Zum Beispiel fast jedes Beispiel ich kenne tut dies:

class A { 
    public: 
    A(std::initializer_list<int>); 
}; 

Aber ich sehe immer wieder dies gelegentlich getan:

class B { 
    public: 
    B(std::initializer_list<int> &&); 
}; 

Ich verstehe die Verwendung und Zweck rvalue Referenzen im Allgemeinen, aber warum sollte eines davon im Fall eines std::initializer_list gegenüber dem anderen bevorzugt werden? Das einzige, was mir einfällt, ist, dass class A erlaubt, dass die Initialisierungsliste separat aufgebaut wird, und class B verhindert dies.

Aber ich kann mir keinen guten Grund vorstellen, warum das zu verhindern eine erstrebenswerte Sache wäre.

Also, warum würde man eine std::initializer_list von Rvalue-Referenz anstelle von Wert nehmen?

+1

Nun, es könnte nur sein, dass jemand wirklich möchte, dass Sie die Liste wörtlich übergeben ... –

+0

Gute Frage, ich habe mich gefragt. By the way, ich denke, 'B b (std :: move (values));' würde immer noch kompilieren. – iavr

+0

Dumme Frage, vielleicht - aber gibt die Implementierung der Rvalue-Referenzversion an irgendeinem der Orte, die Sie gesehen haben, irgendwelche Hinweise? – zmb

Antwort

7

Ich bin nicht sicher, ich habe einen guten Grund, aber meine Vermutung wäre, dass der Autor des Codes gedacht hat, dass eine Initialisiererliste von Wert geben würde unnötige Kopien der Elemente in der Liste. Dies ist natürlich nicht richtig - das Kopieren einer Initialisierungsliste kopiert nicht die zugrunde liegenden Werte.

4

std::initializer_list verkörpert die Referenzsemantik, auch wenn sie als Wert übergeben wird, daher ist die Weitergabe als Referenz im besten Fall irreführend. (Es enthält nur nicht-besitzenden Zeiger.)

Es gibt universelle Referenzen, die an etwas binden, aber sie können nicht durch die verspannt-init-Liste Syntax (dh { x, y }) initialisiert werden, so eine initializer_list getting auf diese Weise würde eine Kombination von Umständen annehmen.

Verwandte Themen