使用set_union和set_intersection时出错

| 我有两个集合,我正在尝试进行并集(在进行相交时会遇到相同的错误)。这是错误:
error C3892: \'std::_Tree_const_iterator<_Mytree>::operator *\' : you cannot assign to a variable that is const
代码段(如果我用->注释掉这一行,则代码会编译,而我做联合工作的方法也可以正常工作):
    set<Line *>::iterator it;
    set<Line *> * newSet = new set<Line *>();
    leftLines = pLeft->getSet();
    rightLines = pRight->getSet();
 -->it = set_union(leftLines->begin(),leftLines->end(),rightLines->begin(), rightLines->end(), newSet->begin());
    for(it = leftLines->begin(); it != leftLines->end(); it++)
    {
        newSet->insert(*it);
    }
    for(it = rightLines->begin(); it != rightLines->end(); it++)
    {
        newSet->insert(*it);
    }
    it = newSet->begin();
    while(it != newSet->end())
    {
        result->insert(*it);
        it++;
    }
我确定这有些愚蠢,但我有点迷失了。我认为该代码段就足够了,但是我可以提供所需的任何内容。谢谢。     
已邀请:
这是C ++,不是Java [edit:或.NET]。您几乎肯定要替换(例如):
set<Line *> * newSet = new set<Line *>();
只是:
set<Line *> newSet;
...或者,更好的是,可能只是:
set<Line> newSet;
尽管根据您发布的代码无法确定某些确定性,但是很有可能您的
left
right
也不应处理指针-如果它们要做任何事情,引用可能更有意义(不过,正如我所说,仅基于您发布的内容,无法确定地说)。 完成此操作后,您将遇到一个小问题:在
set
(或
multiset
map
multimap
)上的“普通”迭代器实际上是const_iterator。将某物插入关联容器后,您将无法对其进行更改,因为这可能会破坏集合的不变性(进行排序)。如果要更改现有项目,则需要从包含中删除,进行更改,然后将更改后的对象重新插入容器。在您的情况下,您只是要插入新项目,因此需要
insert_iterator
。 由于您不打算修改ѭ5或ѭ6,因此最好将它们也视为as14ѭ:
std::set_union(left.cbegin(), left.cend(), 
               right.cbegin(), right.cend(), 
               std::inserter(newSet, newSet.end()));
如果决定自己模拟set_union,则可以执行以下操作:
std::set<Line> newSet(left.cbegin(), left.cend());  
std::copy(right.cbegin(), right.cend(), std::inserter(newSet, newSet.end()));
编辑: 通常,您不希望将迭代器传递到容器中,而不是传递指向容器的指针。例如,要打印出内容,您现在显然具有以下内容:
void print_data(std::vector<Line *> const *data) { 
     for (int i=0; i<data->size(); i++)
         std::cout << *(*data)[i] << \"\\n\";
}
它可能具有更多的格式设置,但目前,我们将忽略这些细节,并假设它是如此简单。要直接从您选择的容器中写入数据,通常需要一个模板来接受任意类型的迭代器:
template <class inIt>
void print_data(inIt begin, inIt end) { 
     while (begin != end) 
         std::cout << *begin++ << \'\\n\';
}
但是,我们可以更进一步,并将输出指定为迭代器:
template <class inIt, class outIt>
void print_data(inIt begin, inIt end, outIt dest) { 
    while (begin != end) {
        *dest++ = *begin++;
        *dest++ = \'\\n\';
    }
}
您可以再走一步,并允许用户指定要在项目之间使用的定界符,而不是始终使用\'\\ n \',但是到那时,您将只复制某些内容。 s已经在标准库中-ѭ20an和
std::ostream_iterator
的组合,这实际上可能是您要处理的方式:
std::copy(newSet.begin(), newSet.end(), 
          std::ostream_iterator<Line>(std::cout, \"\\n\"));
但是请注意,就标准库而言,ѭ23just只是另一个迭代器。如果您只是要打印出
left
right
的并集,则可以跳过甚至创建一个集来保存该并集的集合,而直接将其打印出来:
std::set_union(left.cbegin(), left.cend(),
               right.cbegin(), right.cend(), 
               std::ostream_iterator<Line>(std::cout, \"\\n\"));
ostream_iterator
写入文件而不是将其放入普通集合的事实与标准库完全无关。它具有一些迭代器类,并且可以将输出写入对正确类进行建模的任何迭代器。 现在,可以说,我可能正在jumping步-可能需要在将数据写入控制台之前对数据进行其他处理。我的意思不是,您不一定必须将联合直接写入标准输出,而只是在打印出来之前不必一定要将其写入其他集合。     
set迭代器不是输出迭代器。用这个:
set_union(leftLines->begin(),leftLines->end(),rightLines->begin(), rightLines->end(), inserter(*newSet, newSet->begin()));
还有,为什么要filling29ѭ?在并集/相交之后保持原样,否则并集/相交将毫无意义。
set<Line *>::iterator it;
set<Line *> newSet; // No need to `new` this
leftLines = pLeft->getSet();
rightLines = pRight->getSet();
set_union(leftLines->begin(),leftLines->end(),rightLines->begin(), rightLines->end(), inserter(newSet, newSet.begin()));

// Assuming you really need the below code - you could likely just make an inserter directly on `result` instead of the copying.
it = newSet.begin();
while(it != newSet.end())
{
    result->insert(*it);
    it++;
}
    

要回复问题请先登录注册