I wrote this AddressBook program in C as an exercise, and everything works fine except the removeContact
method.
The compiler (MSVC) reports an issue related, I think, to some sort of incompatible right operand with a ==
operator.
Here's the compiler output:
error C2679: binary '==': no operator found which takes a right-hand operand of type 'std::shared_ptr<Contact>' (or there is no acceptable conversion)
note: could be 'bool std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>::operator ==(const std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<_Ty>>> &) noexcept const' [synthesized expression 'y == x']
with
[
_Ty=Database::ContactPtr
]
note: while trying to match the argument list '(std::shared_ptr<Contact>, const _Ty)'
with
[
_Ty=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Database::ContactPtr>>>
]
note: see reference to function template instantiation '_FwdIt std::remove<std::shared_ptr<Contact>*,_Uty>(_FwdIt,const _FwdIt,const _Ty &)' being compiled
with
[
_FwdIt=std::shared_ptr<Contact> *,
_Uty=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Database::ContactPtr>>>,
_Ty=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Database::ContactPtr>>>
]
note: see reference to function template instantiation 'unsigned int std::_Erase_remove<std::vector<Database::ContactPtr,std::allocator<Database::ContactPtr>>,_Uty>(_Container &,const _Uty &)' being compiled
with
[
_Uty=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Database::ContactPtr>>>,
_Container=std::vector<Database::ContactPtr,std::allocator<Database::ContactPtr>>
]
note: see reference to function template instantiation 'unsigned int std::erase<Database::ContactPtr,std::allocator<Database::ContactPtr>,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>>(std::vector<_Ty,std::allocator<_Ty>> &,const _Uty &)' being compiled
with
[
_Ty=Database::ContactPtr,
_Uty=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<Database::ContactPtr>>>
I don't know if the issue is something really simple, but this report is cryptic. Here's the code:
#include "Database.h"
#include "ContactNotFoundException.h"
void Database::addContact(const Contact &contact) {
contacts.push_back(std::make_shared<Contact>(contact));
}
void Database::removeContact(const Contact &contact) {
removeContact(findContact(contact.getName()));
}
void Database::removeContact(std::string_view name) {
removeContact(findContact(name));
}
void Database::removeContact(const size_t index) {
auto iterator{contacts.begin()};
iterator = static_cast<int>(contacts.size() - index);
std::erase(contacts, iterator);
}
size_t Database::findContact(std::string_view name) const {
// TODO: algorithm
for (size_t i = 0; i < contacts.size(); i) {
if (contacts.at(i)->getName() == name)
return i;
}
throw ContactNotFoundException();
}
Database::ContactPtr Database::getContact(std::string_view name) const {
return contacts.at(findContact(name));
}
void Database::listContacts() const {
for (const auto& contactPtr : contacts) {
std::cout << contactPtr->getName() << std::endl;
}
}
I also have to clarify that I put the compiler output in a code block because StackOverflow wouldn't let me post the answer, as it detects it as code.
CodePudding user response:
std::erase
takes a value which is searched in your container and then removed, not an iterator.
Therefore trying to pass an iterator there triggers an error because std::erase
is trying to compare your container elements with this iterator, but iterators and elements are normally not comparable.
To erase an element you already have an iterator for, you need contacts.erase(iterator)
instead.