#c #g
Вопрос:
Я получаю следующую ошибку при компиляции моей программы на C :
error: no matching function for call to 'std::vectorlt;ChainingTablelt;intgt;::Record, std::allocatorlt;ChainingTablelt;intgt;::Recordgt; gt;::push_back(ChainingTablelt;intgt;::Record*)' 324 | vector_.push_back(new Record(key, value));
Ошибка исходит из строки:
template lt;class TYPEgt; bool ChainingTablelt;TYPEgt;::update(const std::string amp;key, const TYPE amp;value) { if (!keyExists) { vector_.push_back(new Record(key, value)); } }
Это определено для класса:
class ChainingTable : public Tablelt;TYPEgt; { struct Record { TYPE data_; std::string key_; Record(const std::string amp;key, const TYPE amp;data) { key_ = key; data_ = data; } }; std::vectorlt;std::vectorlt;Recordgt;gt; records_; int capacity_; // capacity of the array
Полный код:
int sz = numRecords(); bool rc = true; std::hashlt;std::stringgt; hashFunction; size_t hash = hashFunction(key); size_t idx = hash % capacity_; std::vectorlt;Recordgt; vector_ = records_[idx]; bool keyExists = false; for (int i = 0; i lt; vector_.size(); i ) { if (vector_[i].key_ == key) { vector_[i].data_ = value; keyExists = true; } } if (!keyExists) { vector_.push_back(new Record(key, value)); }
В чем может быть причина этого?
Комментарии:
1. Вы пытаетесь нажать указатель (возвращаемый
new
), но похоже, что вектор инициализирован для использования объектов.2. Что такое переменная типа
vector_
? Я имею в виду, как вы это определили. Можете ли вы показать нам это? Похожеvector_
, в ваших приведенных выше фрагментах нет определения.3. @JohnnyMopp, я добавил полный код. Извините за путаницу
Ответ №1:
Ваш вектор объявлен для хранения объектов типа Record
, а не указателей на них ( Record *
), но вы пытаетесь передать результат operator new
, который возвращает Record *
, просто используйте std::vector::emplace_back
вместо этого:
vector_.emplace_back(key, value);
Примечание: в этой строке
std::vectorlt;Recordgt; vector_ = records_[idx];
вы создаете копию, а затем изменяете ее, похоже, вам нужна ссылка.
Примечание 2: в вашем цикле поиска вы не завершаете, даже если уже нашли объект, вы должны добавить break
в if
оператор, что сделает его более эффективным.
Комментарии:
1. Я добавил полный код, чтобы избежать какой-либо путаницы
2. @daniel это ничего не меняет, мой ответ все еще сохраняется
3. Понял. Но могу ли я тогда сделать
Record *record = new Record(key, value);
и сделать vector_.push_back(*запись)? Это будет нормально?4. @daniel, который будет компилироваться, но вы создадите ненужную копию и вызовете утечку памяти (если вы не удалите ее впоследствии, но все равно сделаете все это ненужным)
5. emplace_back автоматически преобразует его в запись и переместит в вектор?
Ответ №2:
Проблема в том, что ваша переменная vector_
содержит объекты типа Record
, но когда вы пишете:
vector_.push_back(new Record(key, value));
Вы пытаетесь добавить указатель на Record
объект в вектор vector_
вместо добавления самого Record
объекта.
Вы можете решить эту проблему, написав:
vector_.emplace_back(key, value);
Альтернативное решение
Обратите внимание, что есть еще одно возможное решение, которое заключается в использовании:
vector_.push_back(Record(key, value));
Но использование emplace_back
должно быть предпочтительным.