我可能在这里犯了一些基本错误,但是给出了:
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&gt; c:\ program files(x86)\ microsoft visual studio 11.0 \ _vc \ include \ xutility(3186):错误C2678:二进制'==':找不到哪个运算符带有'的左手操作数' int'(或没有可接受的转换)
我错过了什么?
答案 0 :(得分:3)
cppreference on std::find
and std::find_if
std::find
将值作为第三个参数进行比较,而std::find_if
采用UnaryPredicate
(函数对象采用一个参数)。您可能只是输错了/想要使用std::find_if
。
使用std::find_if
对我有用。 Live example
#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到int
的转换,并且没有声明适用于此的比较运算符。