Beim folgenden Code:
%Vor%ist kompiliert mit gcc / libstdc ++ vs. clang / libc ++ binary gibt verschiedene Ergebnisse.
Für gcc / libstdc ++ wird ein Element in alle anderen Referenzen kopiert.
%Vor%Zuerst dachte ich, clang / libc ++ verhält sich wie erwartet , aber es funktioniert nur bis zu 5 Elemente in einem Vektor (weil es einen speziellen Fall für kleine Container gibt).
%Vor%Wenn mehr Elemente übergeben werden, ähnelt das Ergebnis gcc.
%Vor% Also ist es zulässig, std::sort
für Container mit Tupeln mit Referenzen zu verwenden (d. h. mit std::tie
, Sortier-Subset der Struktur)?
Wenn nicht, sollte ich irgendwelche Warnungen erwarten?
Also ist es zulässig,
std::sort
für Container mit Tupeln mit Referenzen zu verwenden (d. h. mitstd::tie
, Sortier-Subset der Struktur)? Wenn nicht, sollte ich irgendwelche Warnungen erwarten?
Nein, und nein. Eine der folgenden Anforderungen für std::sort()
lautet:
- Der Typ der dereferenzierten
RandomIt
muss die Anforderungen vonMoveAssignable
undMoveConstructible
erfüllen.
wo MoveAssignable
im Ausdruck t = rv
:
Der Wert von
t
ist äquivalent zum Wert vonrv
vor der Zuweisung.
Aber std::tuple<int&>
ist nicht MoveAssignable, weil int&
nicht MoveAssignable ist. Wenn Sie einfach haben:
Der Wert von ra
entspricht nicht dem vorherigen Wert von rb
. ra
noch verweist auf a
, bezieht sich nicht auf b
- was sich tatsächlich geändert hat, war der Wert von a
.
Da unser Typ nicht die Bedingung std::sort()
erfüllt, ist das Ergebnis des Aufrufs std::sort()
nur undefiniertes Verhalten.
Beachten Sie, dass Sie trotzdem std::vector<std::tuple<std::reference_wrapper<int>>>
sortieren konnten, weil std::reference_wrapper
ist MoveAssignable.
Beachten Sie auch, dass dies daran erinnert, dass es nicht möglich ist, einen Container mit auto_ptr
nach einem alten Herb Sutter Artikel zu sortieren .