vector ::push _back настаивает на использовании конструктора копирования, хотя предоставляется конструктор перемещения

Я получал странную ошибку от gcc и не могу понять, почему. Я сделал следующий пример кода, чтобы сделать проблему более ясной. По сути, есть определенный класс, для которого я делаю его конструктор копирования и оператор присваивания закрытыми, чтобы предотвратить их случайный вызов.

#include <vector>
#include <cstdio>
using std::vector;

class branch 
{
public:
  int th;

private:
  branch( const branch& other );
  const branch& operator=( const branch& other );

public:

  branch() : th(0) {}

  branch( branch&& other )
  {
    printf( "called! other.th=%d\n", other.th );
  }

  const branch& operator=( branch&& other )
  {
    printf( "called! other.th=%d\n", other.th );
    return (*this);
  }

};



int main()
{
  vector<branch> v;
  branch a;
  v.push_back( std::move(a) );

  return 0;
}

Я ожидаю, что этот код скомпилируется, но он не работает с gcc. На самом деле gcc жалуется, что "ветвь ::ветвь (const branch& )является частной", которую, как я понимаю, не следует называть.

Оператор присваивания работает, так как если я заменю тело main ()на

branch a;
branch b;
b = a;

Он скомпилируется и запустится, как и ожидалось.

Это правильное поведение gcc? Если да, то что не так с приведенным выше кодом? Любое предложение полезно для меня. Благодарю вас!

-121 ---779501 ​​- вектор ::стирание и реверсирование _итератор У меня есть набор элементов в векторе std ::, которые отсортированы в порядке убывания, начиная с первого элемента. Я должен использовать вектор, потому что мне нужно иметь элементы в непрерывном куске...

У меня есть набор элементов в векторе std ::, которые отсортированы в порядке убывания, начиная с первого элемента. Я должен использовать вектор, потому что мне нужно иметь элементы в непрерывном куске памяти. И у меня есть коллекция, содержащая множество экземпляров векторов с описанными характеристиками (, всегда отсортированных в порядке убывания ).

Теперь, иногда, когда я узнаю, что у меня слишком много элементов в большей коллекции (той, которая содержит эти векторы ), я отбрасываю наименьшие элементы из этих векторов в чем-то подобно этому псевдо-коду:

grand_collection: collection that holds these vectors
T: type argument of my vector
C: the type that is a member of T, that participates in the < comparison (this is what sorts data before they hit any of the vectors).

std::map<C, std::pair<T::const_reverse_iterator, std::vector<T>&>> what_to_delete;
iterate(it = grand_collection.begin() -> grand_collection.end())
{
     iterate(vect_rit = it->rbegin() -> it->rend())
     {
         //...
          what_to_delete <- (vect_rit->C, pair(vect_rit, *it))
          if (what_to_delete.size() > threshold)
               what_to_delete.erase(what_to_delete.begin());
         //...  
     }
}

Теперь,после запуска этого кода в what_to_deleteу меня есть набор итераторов, указывающих на исходные векторы, которые я хочу удалить из этих векторов (наименьшие общие значения ). Помните, исходные векторы сортируются до того, как попадут в этот код, а это означает, что для любого what_to_delete[0 - n]итератор в позиции n - mникак не укажет на элемент, расположенный дальше от начала того же вектора, чем n, где m > 0.

При стирании элементов из исходных векторов мне приходится преобразовывать обратный _итератор в итератор. Для этого я полагаюсь на C++11 §24.4.1/1 :

The relationship between reverse_iterator and iterator is &*(reverse_iterator(i)) == &*(i- 1)

. Это означает, что для удаления vect_ritя использую:

vector.erase(--vect_rit.base());

Теперь согласно стандарту C++11§23.3.6.5/3:

iterator erase(const_iterator position); Effects: Invalidates iterators and references at or after the point of the erase.

Как это работает с обратными итераторами _? Являются ли обратные _итераторы внутренне реализованными со ссылкой на реальное начало вектора(vector[0])и преобразовать этот вектор _rit в классический итератор, чтобы стирание было безопасным? Или обратный _итератор использует rbegin()(чтоvector[vector.size()])в качестве контрольной точки и удаление всего, что находится дальше от индекса вектора 0 -, все равно сделает недействительным мой обратный итератор?

Изменить:

Похоже, что обратный _итератор использует rbegin ()в качестве ориентира. Стирание элементов так, как я описал, приводило к ошибкам, связанным с -итератором, подлежащим отслеживанию, после удаления первого элемента. В то время как при сохранении классических итераторов (преобразование вconst_iterator)при вставке в what_to_deleteработал правильно.

Теперь, для справки в будущем, указывает ли Стандарт, что следует рассматривать как контрольную точку в случае обратного _итератора произвольного -доступа? Или это деталь реализации?

Спасибо!

6
задан skst 13 November 2013 в 20:46
поделиться