Информация об изменениях

Сообщение Re[5]: Перенос объекта в map от 03.06.2025 16:39

Изменено 03.06.2025 16:53 rg45

Re[5]: Перенос объекта в map
Здравствуйте, pva, Вы писали:

pva>А конкретней? Или ты имеешь в виду что можно было бы перегрузить дерево и похачить перемещение узла прямо во внутренностях?


Именно так. Вот тебе небольшая демонстрашка:

http://coliru.stacked-crooked.com/a/d3bf6bfc76c950e6

#include <iostream>
#include <map>
#include <string>

struct A {
    std::string name;

    explicit A(const std::string& name) : name(name){}

    A(const A&) = delete;
    A(A&&) = delete;
};

using Map = std::map<int, A>;

void replaceKey(Map& map, int oldKey, int newKey) {
    if (oldKey != newKey) {
        auto&& node = map.extract(oldKey);
        node.key() = newKey;
        map.insert(std::move(node));
    }
}

int main() {
    Map map;
    
    map.emplace(1, "one");
    map.emplace(2, "ten");
    map.emplace(3, "three");

    replaceKey(map, 2, 10);
    
    for(auto&&[key, a] : map) {
        std::cout << key << ", " << a.name << std::endl;
    }
}


Обрати внимание на удалённые конструкторы копирования и перемещения в классе A.
Re[5]: Перенос объекта в map
Здравствуйте, pva, Вы писали:

pva>А конкретней? Или ты имеешь в виду что можно было бы перегрузить дерево и похачить перемещение узла прямо во внутренностях?


Именно так. Вот тебе небольшая демонстрашка:

http://coliru.stacked-crooked.com/a/d3bf6bfc76c950e6

#include <iostream>
#include <map>
#include <string>

struct A {
    std::string name;

    explicit A(const std::string& name) : name(name){}

    A(const A&) = delete;
    A(A&&) = delete;
};

using Map = std::map<int, A>;

void replaceKey(Map& map, int oldKey, int newKey) {
    if (oldKey != newKey) {
        auto&& node = map.extract(oldKey);
        node.key() = newKey;
        map.insert(std::move(node));
    }
}

int main() {
    Map map;
    
    map.emplace(1, "one");
    map.emplace(2, "ten");
    map.emplace(3, "three");

    replaceKey(map, 2, 10);
    
    for(auto&&[key, a] : map) {
        std::cout << key << ", " << a.name << std::endl;
    }
}


Обрати внимание на удалённые конструкторы копирования и перемещения в классе A.

P.S. Само название node-handle намекает на то, что extract возвращает некую обёртку над узлом дерева, а не сам узел.