Скопируйте std :: map of std :: unique_ptr с полиморфным содержимым - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть граф с классом ребер. Я хочу, чтобы ребра были копируемыми, но проблема в том, что ребро содержит std::map из std::unique_ptr полиморфного содержимого. У меня есть базовый класс для информации о краях. Если ребру нужна дополнительная информация, я могу создать подкласс этого информационного класса и добавить его к ребру. Затем эта информация сохраняется на карте с указанием типа информации в качестве ключа.

class Edge {
private:
    std::size_t from;
    std::size_t to;
    std::map<std::type_index, std::unique_ptr<EdgeInformation>> info;
public:
    Edge(std::size_t from, std::size_t to) : from(from), to(to) {
    }

    std::size_t start() const {
        return from;
    }

    std::size_t end() const {
        return to;
    }

    template <typename T, typename... Args>
    void addInfo(Args&&... args) {
        info[typeid(T)] = std::make_unique<T>(std::forward<Args>(args)...);
    }
    template <typename T>
    bool hasInfo() {
        return info.find(typeid(T)) != info.end();
    }
    template <typename T>
    T getInfo() {
        return info[typeid(T)];
    }
    template <typename T>
    void removeInfo() {
        info.erase(std::remove(info.begin(), info.end(), typeid(T)), info.end());
    }

    Edge flipped() const {
        auto flipped_edge = Edge{to, from};
        for(auto &entry : info) {
            // add info to flipped edge here!
        }
        return flipped_edge;
    }
};

Внизу вы видите функцию flipped (), которая должна возвращать ребро с обратным началом и концом. Моя текущая проблема заключается в том, что я не знаю, как скопировать инфо-карту моего края.

Моя EdgeInformation - это просто базовый класс без каких-либо полей или методов.

1 Ответ

0 голосов
/ 26 апреля 2018

Как правильно сказал @ Jarod42, мне просто нужно было добавить метод клона в мой класс EdgeInformation. Так что мой метод flipped () теперь может быть записан как:

Edge flipped() const {
    auto flipped_edge = Edge{to, from};
    for(auto &entry : info) {
        flipped_edge.info[entry.first] = entry.second->clone();
    }
    return flipped_edge;
}

Большое спасибо.

...