Ошибки в C ++ иногда трудно диагностировать. Мой совет - всегда начинать сверху и сначала разрешать. В этом случае есть длинный список из них , но все они на самом деле об одном и том же - оператор присваивания для Mail
не может быть сгенерирован.
Подумайте об этом так, компилятор помогает и пытается сгенерировать (и внутри lower_bound()
, использовать) эту функцию:
Mail& operator=( const& Mail mail )
{
msg = mail.msg;
return *this;
}
Но это невозможно, потому что это присвоение в теле недопустимо из-за того, что msg
является const
. Вы также не можете написать это самостоятельно, так как вы также не можете назначить переменную const
.
Обычно вам не нужно, чтобы переменные-члены были const
, потому что они становятся const
, если сам экземпляр класса const
:
const auto mail1 = Mail{"1"};
auto mail2 = Mail{"2"};
mail1.msg = "3"; // FAIL! msg is const since mail1 is const
mail2.msg = "4"; // Ok! msg is not const
Если вам нужен const
член, вы не можете использовать операторы присваивания с классом. Это перерывы.
Удалите это const
и все работает:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Mail {
public:
Mail(const string & msg) : msg(msg) {}
string msg; //////////////////////////////// Not const!
};
struct Compare {
bool operator()(const Mail & mail, Mail const & mail2) const {
return mail.msg < mail2.msg;
}
};
int main() {
vector <Mail> mails;
Mail mail2("1");
mails.push_back(mail2);
const string msg = "2";
Mail mail(msg);
auto low = lower_bound(mails.begin(), mails.end(), mail, Compare());
// mails.push_back(mail); // OK
mails.insert(low, mail); // OK!
return 0;
}
Смотрите его в прямом эфире Coliru .
Сноска
- Вы можете использовать лямбду для comaparator, чтобы избежать шаблонов вокруг класса
Compare
:
const auto low = lower_bound( begin(mails), end(mails), mail,
[]( const auto& mail1, const auto& mail2 )
{ return mail1.msg < mail2.msg; } );
- Вы можете использовать
vector::emplace_back()
для создания элементов на месте, избегая копирования. Следующие блоки делают то же самое, но второй более эффективен:
const auto mail = Mail{"2"};
mails.push_back( mail2 ); // Copies
mails.emplace_back("2"); // Creates it right in the vector
- Подумайте об использовании
vector::reserve()
, если вы знаете, сколько предметов вы поместите в свой вектор.