Я получал странную ошибку от 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 ::, которые отсортированы в порядке убывания, начиная с первого элемента. Я должен использовать вектор, потому что мне нужно иметь элементы в непрерывном куске памяти. И у меня есть коллекция, содержащая множество экземпляров векторов с описанными характеристиками (, всегда отсортированных в порядке убывания ).
Теперь, иногда, когда я узнаю, что у меня слишком много элементов в большей коллекции (той, которая содержит эти векторы ), я отбрасываю наименьшие элементы из этих векторов в чем-то подобно этому псевдо-коду:
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
работал правильно.
Теперь, для справки в будущем, указывает ли Стандарт, что следует рассматривать как контрольную точку в случае обратного _итератора произвольного -доступа? Или это деталь реализации?
Спасибо!