LINUX.ORG.RU

История изменений

Исправление victor79, (текущая версия) :

то можно в set вместо MyClass положить std::pair<Key, MyClass> и дальше уже для second делать

Да, но это уже получится обычный мап, и это по прежнему не меняет поведение итератора.

то можно попробовать const_cast

это то же не работает, для set типы iterator && const_iterator это одно и то же, о чем упоминается здесь.

В итоге сделал обертку, с использованием которой циклы стали выглядеть цивильно:

template <class Itr, class Data>
struct TmplItr1 {

    TmplItr1(const Itr& ii) : itr(ii) {}

    bool operator==(const TmplItr1&o) const { return itr == o.itr; }
    bool operator!=(const TmplItr1&o) const { return itr != o.itr; }

    Data &operator*() const { return const_cast<Data&>(*itr); }

    void operator++() { ++itr; }

private:
    Itr itr;
};

// и класс который использует этот итератор, в сильно упрощенном виде:
template <class Key, class Data>
struct IdxNode1 {

    struct Cmp {
        bool operator()(const IdxNode1& v1, const IdxNode1& v2) const {
            return v1.p_key < v2.p_key; } };

    using Set = std::set<IdxNode1,Cmp>;
    using iterator = TmplItr1<typename Set::iterator, IdxNode1>;
    
    iterator begin()          { return setNextLevel.begin(); }
    iterator end()            { return setNextLevel.end(); }

    Data data;
    Set setNextLevel;

private:
    Key p_key;
};

Оператор копирования p_key не меняет, и т.д.

Исходная версия victor79, :

то можно в set вместо MyClass положить std::pair<Key, MyClass> и дальше уже для second делать

Да, но это уже получится обычный мап, и это по прежнему не меняет поведение итератора.

то можно попробовать const_cast

это то же не работает, для set типы iterator && const_iterator это одно и то же, о чем упоминается здесь.

В итоге сделал обертку, с использованием которой циклы стали выглядеть цивильно:

template <class Itr, class Data>
struct TmplItr1 {

    TmplItr1(const Itr& ii) : itr(ii) {}

    bool operator==(const TmplItr1&o) const { return itr == o.itr; }
    bool operator!=(const TmplItr1&o) const { return itr != o.itr; }

    Data &operator*() const { return const_cast<Data&>(*itr); }

    void operator++() { ++itr; }

private:
    Itr itr;
};

// и класс который использует этот итератор, в сильно упрощенном виде:
template <class Key, class Data>
struct IdxNode1 {

    struct Cmp {
        bool operator()(const IdxNode1& v1, const IdxNode1& v2) const {
            return v1.p_key < v2.p_key; } };

    using Set = std::set<IdxNode1,Cmp>;
    using iterator = TmplItr1<typename Set::iterator, IdxNode1>;
    
    iterator begin()          { return setNextLevel.begin(); }
    iterator end()            { return setNextLevel.end(); }

    Data data;
    Set setNextLevel;

private:
    Key p_key;
};