Когда следующий код:Можно ли сортировать вектор кортежей ссылок?
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++ против лязга/LibC++ двоичных дают разные результаты.
Для 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
, сортировкой подмножества структуры)? Если нет, следует ли ожидать каких-либо предупреждений?
Использование 'std :: reference_wrapper' работает, потому что оно может быть построено из 'std :: tie', но для получения списка типов T & ... требуется украшение шаблоном шаблона. [Оба компиляторы] (http://melpon.org/wandbox/permlink/atQyUIr1Bh5g6qgn) согласен, что 'станд :: кортеж ' is_move_assignable && is_move_constructible (со стандартными чертами) –
@KarolWozniak Признак может проверить, если только фактическое семантические произведения - вы * можете * переместить присваивание 'tuple'. У этого просто нет фактического поведения, которое эта операция должна иметь, чтобы считаться MoveAssignable. –
Barry
@KarolWozniak Например, 'struct X {int val; X & operator = (X &&) {return * this; }; 'is_move_assignable' истинно, но 'X' на самом деле не MoveAssignable, поскольку это требование не выполняется. –
Barry