【问题标题】:Comparing the contents of two different lists比较两个不同列表的内容
【发布时间】:2018-03-08 08:08:50
【问题描述】:

我正在尝试比较两个不同列表的内容。我正在使用迭代器来遍历列表。我正在检查列表 1 中的最后一个元素是否出现在列表 2 中。这是代码的 sn-p

            /* This section will loop through the list to make sure that the line segment that was added to the 
             * contour path is updated to be visited
             */ 
            for(plf::colony<edgeLineShape>::iterator lineIterator = p_lineList->begin(); lineIterator != p_lineList->end(); lineIterator++)
            {
                edgeLineShape temp = *lineIterator;
                if(temp == *(pathContour.back()))
                {
                    lineSet = true;
                    lineIterator->setVisitedStatus(true);
                    break;
                }
}

pathContour 定义为std::vector&lt;edgeLineShape&gt; pathContour。这是棘手的部分,我在两个不同的容器之间进行比较。实际上是两种不同的数据结构。值得庆幸的是 plf::colony 数据类型满足 C++ 容器的要求,但不满足。

当我去编译时,我在该行给出了一个错误:

if(temp == *(pathContour.back())

这是这一行的错误:

error: no match for 'operator*' (operand type is '__gnu_cxx::__alloc_traits<std::allocator<edgeLineShape> >::value_type {aka edgeLineShape}')

我目前对迭代器的 * 运算符的理解是,它将取消引用迭代器,就像使用 * 运算符取消引用指针一样?

这不正确吗?

【问题讨论】:

  • std::vector&lt;T&gt;::back() 不返回迭代器。它返回对最后一个元素的引用,因此无需使用 operator* 取消引用它
  • 另外:如果pathContour 为空,*(pathContour.back() 会导致未定义的行为。

标签: c++ list iterator containers


【解决方案1】:

您问题中的代码不是比较容器。也许这是一个 XY 问题?

与您的代码等效的 C++ic 是:

#include <algorithm>

auto it = std::find(p_lineList->begin(), p_lineList->end(), , pathCountour.back());
if (it != p_lineList->end()) { /* element found */ } 

但也许你应该考虑一些其他可以避免线性搜索的容器。

【讨论】:

    【解决方案2】:

    因为back 返回的是引用,而不是迭代器(注意错误内容:(operand type is 'blablabla {aka edgeLineShape}'))。您可以像平常一样进行比较:

    if (temp == pathContour.back())
    

    但实际上,temp 不是必需的,因为你只是在这里使用它,所以你可以这样做

    if (*lineIterator == pathContour.back())
    

    另外,如果你使用的是 C++11 或更高版本,你应该查看auto,它可以变成这样:

    for(plf::colony<edgeLineShape>::iterator lineIterator = p_lineList->begin(); lineIterator != p_lineList->end(); lineIterator++)
    

    进入这个:

    for (auto lineIterator = p_lineList->begin(); lineIterator != p_lineList->end(); lineIterator++)
    

    或 foreach,它可以将其浓缩为更简洁:

    for (auto lineIterator : p_lineList)
    

    【讨论】:

    • +1 表示关于冷凝的建议。我实际上使用的是 C++11。自动使用从来没有像你刚才那样简单地向我说明,谢谢!
    • 标记为已回答,因为这是我走的路线!
    【解决方案3】:

    正如 Semyon 所提到的,它是一个参考,因此您不能简单地使用 derefence 运算符。

    但是,你可以这样做:

    *(pathContour.end()--)
    

    如果您坚持使用迭代器。

    【讨论】:

    • 嗯,我确实喜欢这个想法,而且它肯定会奏效,但谁能提出另一种做同样事情的方法?这是最好的做法吗?
    • 在这种情况下最好使用std::prev。
    • 如果 pathCountour 为空怎么办?
    • @ROX 感谢您指出这一点。在示例中,我们将假设它不为空,但我将确保进行检查以确保在为空时不会发生这种情况
    猜你喜欢
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    相关资源
    最近更新 更多