0

我可能在这里犯了一些基本错误,但给出了:

std::array<int, 3> arr = { 1, 2, 3 };
std::vector<int> vecint;
vecint.push_back(1);
vecint.push_back(2);

这是将 arr 中的元素与 vecint 中的元素进行比较的一种明显方法。

std::for_each(vecint.begin(), vecint.end(), [&arr](int vecvalue) {
    for (auto arritr = arr.begin(); arritr != arr.end(); ++arritr) {
        if (vecvalue == *arritr) {
            std::cout << "found!!! " << vecvalue << "\n";
        }
    }
});

但是,我也应该能够这样做吗?

std::for_each(vecint.begin(), vecint.end(), [&arr](int vecvalue) {
    if (std::find(arr.begin(), arr.end(), [=](int arrval) { return vecvalue == arrval; }) != arr.end()) {
        std::cout << "found!!! " << vecvalue << "\n";
    }
});

后者在 VC11 中编译失败,出现以下错误:

1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(3186): error C2678: binary '==' : no operator found which take a left-hand operand of type 'int' (或者没有可接受的转换)

我错过了什么?

4

1 回答 1

3

cppreference onstd::findstd::find_if

std::find接受一个作为第三个参数进行比较,而std::find_if接受一个UnaryPredicate(一个函数对象接受一个参数)。您可能只是有一个错字/想要使用std::find_if.

使用std::find_if对我有用。活生生的例子

#include <array>
#include <vector>
#include <iostream>
#include <algorithm>


int main()
{
    std::array<int, 3> arr = {{ 1, 2, 3 }};
    std::vector<int> vecint;
    vecint.push_back(1);
    vecint.push_back(2);

    std::for_each
    (
        vecint.begin(), vecint.end(),
        [&arr](int vecvalue)
        {
            if (std::find_if(arr.begin(), arr.end(),
                             [=](int arrval) { return vecvalue == arrval; })
                != arr.end())
            {
                std::cout << "found!!! " << vecvalue << "\n";
            }
        }
    );
}

更简单的版本当然是使用std::find(正确):

    std::for_each
    (
        vecint.begin(), vecint.end(),
        [&arr](int vecvalue)
        {
            if (std::find(arr.begin(), arr.end(), vecvalue) != arr.end())
            {
                std::cout << "found!!! " << vecvalue << "\n";
            }
        }
    );

然后,当然还有基于范围的循环变体,如果你的编译器支持它:

for(auto const& ve : vecint)
{
    for(auto const& ae : arr)
    {
        if(ve == ae)
        {
            std::cout << "found!!! " << ve << "\n";
        }
    }
}

如果您的范围已排序,则有更快的算法来获取交集。您可以编写自己的循环来为交集中的每个元素调用一个操作,或者让标准库将交集复制到新容器中:

#include <iterator> // additionally

std::vector<int> result;
std::set_intersection(arr.begin(), arr.end(), vecint.begin(), vecint.end(),
                      std::back_inserter(result));
for(auto const& e : result)
{
    std::cout << e << std::endl;
}

幕后发生的事情 - 为什么会出现该错误:

std::find定义为(来自 cppreference):

template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );

也就是说,value迭代器的类型和类型是独立的。但是,在 的实现中std::find,必须进行如下比较:

if(*first == value) { return first; }

在这一点上,您正在将int(表达式的类型*first) 与 lambda (的类型value)进行更精确的比较:与闭包类型。这是格式错误的(幸运的是),因为没有从 lambda 到 an 的转换int,并且没有声明适用于此处的比较运算符。

于 2013-08-05T00:36:57.333 回答