I can't use std::set_union because I'm not overloading the assignment operator correctly.
I'm using a std::set of my own struct, NodeChange_t, which itself contains another struct, point_t. Here are these guys' operator overloads:
// ---- 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());
...
}
In this case, I want *nodeChanges to be overwritten. But the error I keep getting is:
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)
How does it even make sense that an assignment operator would be marked const, if the whole point is to modify what's on the left hand side? I've been messing around with the const qualifier but can't seem to get anywhere. Any help is appreciated.
The assignment operator is not marked
const. In fact, the error message says as much; it is one of the triggers for the error. Take another look at the relevant parts of the error message with some key emphasis:The other trigger for the error is that the object receiving the assignment is marked
const. If you look around the types mentioned in the error message, you might notice "const_iterator". This is your clue! Somewhere a constant iterator is being de-referenced and a value assigned to the result. All iterators involved aresetiterators, so let's take a look at documentation forset. Aset'siteratortype is a constant iterator; you cannot write to it. (For aset, theiteratorandconst_iteratortypes are usually aliases for the same type. This redundancy allows an interface that is consistent with other containers.)The
set_unionalgorithm requires an output iterator for the destination. Asetdoes not have an output iterator. So even though the word "set" appears in "set_union",set_unioncannot directly output aset.Also concerning is another detail from the
set_uniondocumentation: "The resulting range cannot overlap with either of the input ranges." You cannot accomplish what you want (replace one of the inputs with the union) in one step withset_union. If that is the tool you want to use, you'll need to output the union to an auxiliary container, then updatenodeChangesin a separate step. Hoewever, it would probably be simpler to useset::insert(variation 5):