push_back в векторе в объекте - PullRequest
1 голос
/ 04 января 2012

У меня есть класс профессора с этим атрибутом

vector<int> hDisponibles;

Если у меня есть вектор этого класса

set<profesor> profesores;

Я пробую это

set<profesor>::iterator itP;
itP = profesores.begin();    
while ( itP != profesores.end() ){                
    (*itP).hDisponibles->push_back(0);                                                    
    itP++;
}

, ноэто ошибки

utils.cpp:138: error: passing ‘const std::vector<int, std::allocator<int> >’ as ‘this’     argument of ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int, _Alloc = std::allocator<int>]’ discards qualifiers

Ответы [ 3 ]

4 голосов
/ 04 января 2012

std::set предлагает только константные итераторы, потому что изменение объектов, находящихся в наборе, нарушит инвариант набора.Таким образом, вы не можете делать то, что хотите с std::set, вам нужно либо прочитать новый объект, либо использовать другой контейнер.

3 голосов
/ 04 января 2012

Ваша проблема в том, что vector, который вы пытаетесь вызвать push_back, это const.Это потому, что (начиная с C ++ 11) элементы std::set доступны через const_iterators, поскольку их изменение может изменить их сравнение и, следовательно, испортить set.Чтобы решить эту проблему, у вас есть два варианта:

  1. Если hDisponibles не влияет на сравнение profesor и не наносит большого ущерба вашей общей структуре, вы можете объявить его mutableкак это: mutable vector<int> hDisponibles;.mutable члены могут быть изменены, даже если структура, в которой они находятся, является const
  2. I, что не является опцией, вы должны удалить profesor из набора (во временную), сделатьpush_back и вставьте его снова (будьте осторожны с аннулированием итератора).Конечно, это довольно дорого.

Ваш опубликованный код содержит дополнительную ошибку, поскольку hdisponsibles является объектом, но push_back вызывается так, как если бы он был указателем.Из вашего сообщения компилятора не похоже, что ошибка присутствует в вашем реальном коде, но на всякий случай должно быть:

(*itP).hDisponibles.push_back(0);    

Редактировать: Найден раздел в стандартном черновике (тип значения совпадает с ключом для set и multiset: N3290 §23.2.4 / 6

итератор ассоциативного контейнера относится к категории двунаправленных итераторов. Для ассоциативных контейнеров, гдетип значения совпадает с типом ключа, итератор и const_iterator являются постоянными итераторами. Не определено, являются ли итераторы и const_iterator одинаковым типом. [Примечание: итератор и const_iterator имеют одинаковую семантику в этом случае, и итератор является конвертируемымк const_iterator. Пользователи могут избежать нарушения правила единого определения, всегда используя const_iterator в своих списках параметров функции. —endnote]

1 голос
/ 04 января 2012

Очевидная ошибка в вашем коде состоит в том, что вы используете -> вместо . в этой строке:

(*itP).hDisponibles->push_back(0);  // should be itP->hDisponibles.push_back(0);

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

...