0

我不能使用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预选赛,但似乎无处可去。任何帮助表示赞赏。

4

1 回答 1

2

const如果重点是修改左侧的内容,那么标记赋值运算符有什么意义?

赋值运算符未标记const。实际上,错误消息说明了很多;这是错误的触发器之一。再看一下错误消息的相关部分,重点强调:

候选函数不可行:“this”参数的类型为 [snipped](又名“ const ct”),但方法未标记为 const

该错误的另一个触发因素是接收分配的对象被标记const。如果您查看错误消息中提到的类型,您可能会注意到“ const_iterator”。这是你的线索!某个地方正在取消引用常量迭代器并为结果分配一个值。所有涉及的迭代器都是set迭代器,所以让我们看一下set. Asetiterator类型是一个常量迭代器;你不能写信给它。(对于 a setiteratorandconst_iterator类型通常是同一类型的别名。这种冗余允许接口与其他容器一致。)

set_union算法需要目的地的输出迭代器。Aset没有输出迭代器。所以即使“set_union”中出现“set”这个词,set_union也不能直接输出一个set.

同样令人担忧的是文档中的另一个细节set_union“结果范围不能与任何一个输入范围重叠。” 您无法使用 . 一步完成您想要的(用并集替换其中一个输入)set_union。如果这是您要使用的工具,则需要将联合输出到辅助容器,然后nodeChanges在单独的步骤中更新。但是,使用起来可能会更简单set::insert(变体 5):

nodeChanges->insert(additions.begin(), additions.end());
于 2019-01-21T06:31:51.040 回答