2013-08-05 113 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