Почему перегрузка оператора-кандидата '=' должна быть помечена как const?

Я не могу использовать std::set_union потому что я не перегружаю оператор присваивания правильно.

Я использую std::set моей собственной структуры, NodeChange_t, который сам содержит другую структуру, point_t, Вот перегрузки операторов этих парней:

// ---- defs.h
struct point_t
{
    double x;
    double y;

    ...

    void operator=(const point_t &p)
    {
        x = p.x;
        y = p.y;
    }

    ...

};


struct NodeChange_t
{
    SNode node;
    point_t change;
    ListDigraph *graph;

    ...

    void operator=(const NodeChange_t &otherChange)
    {
        this->node = otherChange.node;
        this->change = otherChange.change;
        this->graph = otherChange.graph;
    }

    ...

};

// ---- _2DSurface.cpp

//Problematic code:
void _2DSurface::updateInnerSurfaceV2(_2DSurface &outerSurf, std::set<NodeChange_t> *nodeChanges)
{
    std::set<NodeChange_t> additions;

    ...

    // add stuff to additions
    std::set_union(additions.begin(), additions.end(), nodeChanges->begin(), nodeChanges->end(), nodeChanges->begin());

    ...

}

В этом случае я хочу *nodeChanges быть перезаписанным. Но ошибка, которую я продолжаю получать:

src/_2DSurface.cpp:308:7: note: in instantiation of function template specialization
      'std::__1::set_union<std::__1::__tree_const_iterator<ct, std::__1::__tree_node<ct, void *> *, long>,
      std::__1::__tree_const_iterator<ct, std::__1::__tree_node<ct, void *> *, long>, std::__1::__tree_const_iterator<ct,
      std::__1::__tree_node<ct, void *> *, long> >' requested here
        std::set_union(nodeChanges->begin(), nodeChanges->end(), additions.begin(), additions.end(), nodeChanges.begin());
include/defs.hpp:258:7: note: candidate function not viable: 'this' argument has type 'const std::__1::__tree_const_iterator<ct,
      std::__1::__tree_node<ct, void *> *, long>::value_type' (aka 'const ct'), but method is not marked const
        void operator=(struct ct &otherChange)

Как это вообще имеет смысл, что оператор присваивания будет помечен const, если весь смысл изменить то, что находится на левой стороне? Я возился с const квалификатор, но, кажется, никуда не денется. Любая помощь приветствуется.

1 ответ

Как это вообще имеет смысл, что оператор присваивания будет помечен const, если весь смысл изменить то, что находится на левой стороне?

Оператор присваивания не помечен const, На самом деле, сообщение об ошибке говорит так же; это один из триггеров для ошибки. Посмотрите еще раз на соответствующие части сообщения об ошибке с некоторыми ключевыми акцентами:

функция-кандидат недопустима: аргумент 'this' имеет тип [snipped] (он же const ct), но метод не помечен как const

Другой триггер для ошибки - то, что объект, получающий назначение, отмечен const, Если вы посмотрите вокруг типов, упомянутых в сообщении об ошибке, вы можете заметить " const_iterator Msgstr "Это ваша подсказка! Где-то разыменовывается постоянный итератор и присваивается значение результату. Все задействованные итераторы set итераторы, так что давайте посмотрим на документацию для set, set "s iterator тип - постоянный итератор; Вы не можете писать в него. (Для set, iterator а также const_iterator типы обычно являются псевдонимами для одного типа. Эта избыточность обеспечивает интерфейс, совместимый с другими контейнерами.)

set_union Алгоритм требует выходной итератор для назначения. set не имеет выходного итератора. Таким образом, хотя слово "набор" появляется в "set_union", set_union не может напрямую выводить set,

Также касается еще одна деталь из set_union Документация: "Результирующий диапазон не может перекрываться ни с одним из входных диапазонов". Вы не можете выполнить то, что вы хотите (заменить один из входов с объединением) в один шаг с set_union, Если это инструмент, который вы хотите использовать, вам нужно вывести объединение во вспомогательный контейнер, а затем обновить nodeChanges в отдельном шаге. Однако, вероятно, было бы проще использовать set::insert (вариант 5):

nodeChanges->insert(additions.begin(), additions.end());
Другие вопросы по тегам