使用 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++;
}
我确信这很愚蠢,但我很友善的丢失。我认为代码片段应该足够了,但我可以提供其他需要的内容。谢谢。
I have two sets and I'm trying to do a union (I get the same error when doing an intersection). Here is the error:
error C3892: 'std::_Tree_const_iterator<_Mytree>::operator *' : you cannot assign to a variable that is const
Code snippet(if I comment out the line with the --> then the code compiles and my work around way of doing the union works fine):
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++;
}
I'm sure this is something silly but I'm kind of lost. I think that code snippet should be enough but I can provide whatever else is needed. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是 C++,而不是 Java [编辑:或 .NET]。您几乎肯定想将(例如):替换
为:
...或者,更好的是,可能只是:
虽然根据您发布的代码不可能确定,但您的
left
和right
也不应该处理指针——如果它们要做任何类似的事情,引用可能更有意义(尽管,正如我所说,仅根据您发布的内容,无法确定)。完成此操作后,您会遇到一个小问题:
set
(或multiset
、map
或set
上的“正常”迭代器code>multimap) 实际上是一个 const_iterator。一旦将某些内容插入到关联容器中,就不允许更改它,因为这可能会破坏集合的不变量(正在排序)。如果要更改现有项目,则需要从容器中删除该项目,进行更改,然后将更改后的对象插入回容器中。就您而言,您只是插入新项目,因此您需要一个insert_iterator
。由于您不打算修改
left
或right
,因此您也可以将它们视为const
:如果您决定模拟如果您自己使用 set_union ,您可以执行以下操作:
编辑:
您通常希望将迭代器传递到容器中,而不是传递指向容器的指针。例如,要打印内容,您显然现在有类似的内容:
它可能有更多格式等,但目前我们将忽略这些细节并假设它就是这么简单。要直接从您选择的容器写入数据,您通常需要一个能够接受任意类型的迭代器的模板:
但是,我们可以更进一步,并将输出指定为迭代器:
您可以再走一步,允许用户指定在项目之间使用的分隔符,而不是总是使用 '\n',但此时,您只需复制标准库中已有的内容即可 -
std::copy
和std::ostream_iterator
的组合,这就是您在现实中可能想要处理这个问题的方式:但是请注意,就标准而言库关心,
ostream_iterator
只是另一个迭代器。如果您只想打印left
和right
的并集,您甚至可以跳过创建一个集合来保存该并集,而直接将其打印出来:事实上,ostream_iterator 写入文件而不是将内容放入普通集合中,这一事实与标准库完全无关。它有几个迭代器类,并且可以将输出写入任何建模正确类的迭代器。
现在,可以这么说,我可能有点操之过急——在将数据写入控制台之前,可能需要对数据进行其他处理。我的观点并不是说您必须将联合直接写入标准输出,而是说您不一定必须在打印之前将其写入其他集合。
This is C++, not Java [edit: or .NET]. You almost certainly want to replace (for example):
with just:
...or, better still, probably just:
Although it's impossible to say for certain based on the code you've posted, there's a pretty fair chance that your
left
andright
shouldn't be dealing in pointers either -- if they're going to do anything of the sort, a reference probably makes more sense (though, as I said, based on just what you've posted, it's impossible to say for sure).Once you've done that, you run into a minor problem: a "normal" iterator over a
set
(ormultiset
,map
ormultimap
) is really a const_iterator. Once you insert something into an associative container, you're not allowed to change it because that could destroy the collection's invariant (being sorted). If you want to change an existing item, you need to delete if from the contain, make the change, and insert the changed object back into the container. In your case, you're just inserting new items, so you want aninsert_iterator
.Since you're not planning on modifying either
left
orright
, you might as well treat them asconst
as well:If you decide to simulate set_union on your own, you can do something like this:
Edit:
Instead of passing around pointers to containers, you normally want to pass around iterators into the containers. For example, to print out the contents, you apparently now have something like:
It probably has more formatting and such, but for the moment we'll ignore those details and assume it's this simple. To write the data directly from a container of your choice, you normally want a template that will accept iterators of an arbitrary type:
We can, however, go a step further than that, and specify the output as an iterator as well:
You could go one more step, and allow the user to specify the delimiter to be used between the items, instead of always using '\n', but at that point, you'd just be duplicating something what's already in the standard library -- a combination of
std::copy
and anstd::ostream_iterator
, which is how you probably want to deal with this in reality:Note, however, that as far as the standard library cares, an
ostream_iterator
is just another iterator. If you're just going to print out the union ofleft
andright
, you can skip even creating a set to hold that union, and just print it out directly:The fact that an
ostream_iterator
writes to a file instead of putting things into a normal collection is entirely irrelevant to the standard library. It has a few classes of iterators, and can write output to any iterator that models the correct class.Now, I may be jumping the gun, so to speak -- maybe need to do other processing on the data before you write it to the console. My point isn't that you necessarily have to write the union directly to standard output, but just that you don't necessarily have to write it to some other collection before you print it out.
设置迭代器不是输出迭代器。使用这个:
另外,你为什么要填充
newSet
?在并集/交集之后保持原样,否则并集/交集将毫无意义。set iterators aren't output iterators. Use this:
Also, why're you filling
newSet
? Leave it as is after the union/intersection or the union/intersection will be pointless.