Могу ли я сортировать вектор кортежа ссылок?
при следующем коде:
std::vector<std::tuple<int&>> v;
int a = 5; v.emplace_back(a);
int b = 4; v.emplace_back(b);
int c = 3; v.emplace_back(c);
int d = 2; v.emplace_back(d);
int e = 1; v.emplace_back(e);
std::sort(std::begin(v), std::end(v));
компилируется с GCC/libstdc++ vs Clang / libc++ binary дает разные результаты.
на gcc / libstdc++ один элемент копируется во все остальные ссылки.
5 4 3 2 1
5 5 5 5 5
сначала я подумал, что clang / libc++ поведение как и ожидалось но он работает только до 5 элементов в векторе (есть специальный чехол для небольших емкостей).
5 4 3 2 1
1 2 3 4 5
когда передача большего количества элементов результат аналогичен gcc.
5 4 3 2 1 0
3 4 5 5 5 5
так это действительно использовать std::sort
для контейнера кортежей со ссылками (т. е. заключил с std::tie
, сортировка подмножества структуры)?
Если нет, следует ли ожидать каких-либо предупреждений?
1 ответов
так это действительно использовать
std::sort
для контейнера кортежей со ссылками (т. е. заключил сstd::tie
, сортировка подмножества структуры)? Если нет, следует ли ожидать каких-либо предупреждений?
нет, и нет. Одно из требований типа на std::sort()
это:
- тип разыменован
RandomIt
должны соответствовать требованиямMoveAssignable
иMoveConstructible
.
здесь MoveAssignable
требуется в выражении t = rv
:
значение
t
is эквивалентно стоимостьюrv
до назначения.
но std::tuple<int&>
не является MoveAssignable, потому что int&
не является MoveAssignable. Если у вас просто есть:
int& ra = a;
int& rb = b;
ra = std::move(rb);
значение ra
не эквивалентно предыдущему значению rb
. ra
еще относится to a
, он не изменяется, чтобы ссылаться на b
- на самом деле изменилось значение a
.
так как наш тип не соответствует условию std::sort()
результат std::sort()
вызовы-это просто неопределенное поведение.
обратите внимание, что вы мог бы сортировать std::vector<std::tuple<std::reference_wrapper<int>>>
, потому что std::reference_wrapper
является MoveAssignable.
обратите внимание также, что это напоминает невозможность сортировки контейнера auto_ptr
, за старую траву Саттер статьи.