12

要使用 POD 元素搜索 C 数组中第一次出现的元素,可以使用std::find_if(begin, end, findit). 但我需要最后一次出现。这个答案让我想到可以用std::reverse_iterator. 因此我尝试了:

std::find_if(std::reverse_iterator<podtype*>(end),
             std::reverse_iterator<podtype*>(begin),
             findit);

这给了我错误:

无法在赋值中将 'std::reverse_iterator< xyz* >' 转换为 'xyz*'

您是否知道如何以这种方式进行操作,或者您知道更好的解决方案?

这是代码:

#include <iostream>
#include <iterator>
#include <algorithm>

struct xyz {
    int a;
    int b;
};

bool findit(const xyz& a) {
    return (a.a == 2 && a.b == 3);
}

int main() {
    xyz begin[] = { {1, 2}, {2, 3}, {2, 3}, {3, 5} };
    xyz* end = begin + 4;

    // Forward find
    xyz* found = std::find_if(begin, end, findit);
    if (found != end)
        std::cout << "Found at position "
                  << found - begin
                  << std::endl;

    // Reverse find
    found = std::find_if(std::reverse_iterator<xyz*>(end),
                         std::reverse_iterator<xyz*>(begin),
                         findit);
    if (found != std::reverse_iterator<xyz*>(end));
        std::cout << "Found at position "
                  << found - std::reverse_iterator<xyz*>(end)
                  << std::endl;

    return 0;
}

以及codepad.org 上的编译器错误

4

1 回答 1

16

std::find_if函数的返回类型等于作为参数传入的迭代器的类型。在您的情况下,由于您将std::reverse_iterator<xyz*>s 作为参数传入,因此返回类型将为std::reverse_iterator<xyz*>. 这意味着

found = std::find_if(std::reverse_iterator<xyz*>(end),
                     std::reverse_iterator<xyz*>(begin),
                     findit);

不会编译,因为foundxyz*.

要解决此问题,您可以尝试以下操作:

std::reverse_iterator<xyz*>
rfound = std::find_if(std::reverse_iterator<xyz*>(end),
                      std::reverse_iterator<xyz*>(begin),
                      findit);

这将修复编译器错误。但是,我认为您在这一行中有两个次要错误:

if (found != std::reverse_iterator<xyz*>(end));

首先,请注意语句后面有一个分号,因此无论条件是否为真,都会评估语句if的主体。if

其次,请注意,std::find_if如果没有与谓词匹配,则将第二个迭代器作为哨兵返回。因此,该测试应

if (rfound != std::reverse_iterator<xyz*>(begin))

因为如果找不到元素,find_if将返回。std::reverse_iterator<xyz*>(begin)

希望这可以帮助!

于 2013-06-19T21:22:36.527 回答