std :: map: создание / замена элемента, когда он не является конструируемым по умолчанию - PullRequest
2 голосов
/ 15 января 2020

Предположим, у вас есть класс, который не является конструктивным по умолчанию.

class A {
  private:
    int a;
  public:
    A() = delete;
    A(int a0) : a(a0) {}
};

Теперь у нас есть карта Int -> A, std::map<int, A> mapping. Допустим, мы хотим создать новое отображение для некоторого ключа 0, и если ключ существует, мы хотим заменить старое значение. Способ сделать это для классов, конструируемых по умолчанию, таков:

mapping[0] = A(4);

Это, однако, не удастся для класса A, потому что operator [] сначала создает экземпляр A по умолчанию, и только затем ему присваивается значение. A(4). Один из способов сделать это в целом (то есть для классов, не конструируемых по умолчанию) заключается в следующем:

auto it = mapping.find(0);
if (it == mapping.end()) {
  mapping.insert(0, A(4));
}
else {
  it->second = A(4);
}

Мой вопрос: действительно ли это (C ++) предназначен для этого? Я чувствую, что это не может быть правильно; как программист, я не хочу писать так много кода за такое маленькое. Но, похоже, нет простого выхода: я посмотрел общие методы карты (insert, emplace, emplace_hint) и все они ничего не делают, если ключ уже присутствует.

1 Ответ

5 голосов
/ 15 января 2020

Я посмотрел общие методы карты (insert, emplace, emplace_hint) и все они ничего не делают, если ключ уже присутствует.

C ++ 17 обратились к этой точке с std::map::insert_or_assign:

template <class M>
pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);

Если ключ, эквивалентный k, уже существует в контейнере, присваивает std::forward<M>(obj) mapped_type, соответствующему ключу k. Если ключ не существует, вставляет новое значение как будто путем вставки, создавая его из value_type(k, std::forward<M>(obj)).

Это делает

auto it = mapping.find(0);
if (it == mapping.end()) {
  mapping.insert(0, A(4));
}
else {
  it->second = A(4);
}

похожим на

mapping.insert_or_assign(0, A(4));

демонстрация полной программы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...