2013-08-05 74 views
0

我可能做一些基本的错误,在这里,但给出:麻烦与嵌套Lambda表达式

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:\程序文件(86)\微软的Visual Studio 11.0 \ VC \包括\ xutility(3186):错误C2678 :二进制'==':没有发现操作符需要类型'int'的左侧操作数(或没有可接受的转换)

我在想什么?

回答

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类型和ITE的类型老师是独立的。然而,在std::find的实施,必须有一个比较像:

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

在这一点上,你与拉姆达比较的int(型表达*first的)(类型value更确切地说:关闭类型为。这是不合格的(幸运的是),因为没有从lambda转换为int,并且没有比较运算符声明它适用于此。

+0

谢谢!对我来说,这是一个愚蠢的疏忽。 – ForeverLearning