首页 > 解决方案 > C++ 设置迭代器错误:'operator+=' 不匹配

问题描述

我正在尝试遍历一组对象并创建一个逗号分隔的名称字符串。代码的注释掉部分应该只在它不是集合中的最后一个时添加一个逗号,但它会生成以下错误:

错误:'operator+=' 不匹配(操作数类型是 'std::_Rb_tree_const_iterator' 和 'long int')_M_current += -__n;

如果我使用向量而不是集合,它工作正常。我究竟做错了什么?

std::string paramList = "";
std::set<Param>::iterator end = params.end();
for (std::set<Param>::iterator it = params.begin(); it != end; ++it) {
  paramList += (*it).name;
  /*if (it != end -1) {
    paramList += ",";
  }*/
}

标签: c++

解决方案


只有某些类别的迭代器允许您直接执行任意算术运算,例如end-1.

集合的迭代器允许一次前进和后退一步,使用it++and it--。确实,它it - 1仍然只遍历了一步,但规则更通用(语言不知道您提供的整数是公正的1,也没有理由与,例如,做一个特殊情况42)。

可以使用std::next/std::prev来获得这种行为。这故意更冗长,以阻止您对迭代器进行任意算术,这对于这种迭代器来说比对于简单的类似数组的东西(如向量)更昂贵。

在这种情况下,std::prev(end)它将为您工作,并且是合理的惯用语。

但是,如果您发现自己在编写类似 的std::next(it, 42)内容,您可能需要考虑改进您的算法,或者使用不同的容器。

同样,这个限制的目的是鼓励这种想法。

编写算法的另一种方法可能是:

std::string paramList;
std::set<Param>::iterator begin = params.begin(), end = params.end();
for (std::set<Param>::iterator it = begin; it != end; ++it) {
  if (it != begin)
    paramList += ",";

  paramList += (*it).name;
}

请注意我是如何翻转逻辑以避免需要进行任何算术运算的。

实际上,我通常bool为此使用一个标志(当我是一个字符串流时),或者如果它是非空的,则paramList总是附加一个,然后缩小paramList一个(当它是一个字符串时) 。params


推荐阅读