Почему перегрузка оператора-кандидата '=' должна быть помечена как 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());