2013-01-18 72 views
0

我不明白爲什麼這不起作用。我有一個函數返回std::find方法的結果。我讀過它返回一個迭代器來找到它的對象。但是,當我嘗試傳遞返回該值的lambda時,它給了我一堆錯誤,爲什麼?爲什麼我不能獲得std :: function <std :: vector <T> :: iterator>綁定到返回該類型的lambda?

void f(std::function<std::vector<int>::iterator()>) {} 

int main() 
{ 
    std::vector<int> v{0, 1, 2, 3}; 

    auto p = [=] (int n) { 
     return std::find(v.begin(), v.end(), n); 
    }; 

    f(p); 
} 

我收到很多不可理解的錯誤。我甚至在這裏做了類型檢查和真的返回:

std::is_same<std::vector<int>::iterator, decltype(std::find(v.begin(), v.end(), N))>::value; 
// -> true 

那麼,爲什麼這個工作時,我傳遞給f功能與std::function返回此類型的?

+0

你能提供一個關於你得到的錯誤的提示嗎?只是第一個或第二個;之後他們通常是無稽之談。 –

回答

4

假設int參數在std::function參數丟失的是一個複製粘貼錯誤,顯然v.begin()v.end()回報const_iterator真是讓人比正常迭代器。

這是由於您的lambda按值捕獲,使您的std::vectorconst(以及它的迭代器)。通過參考works捕捉一切,否則,你的std::function應該返回const_iterator:默認情況下

#include <vector> 
#include <functional> 
#include <algorithm> 

void f(std::function<std::vector<int>::iterator (int)>) {} 

int main() 
{ 
    std::vector<int> v{0, 1, 2, 3}; 

    auto p = [&] (int n) { 
     return std::find(v.begin(), v.end(), n); 
    }; 

    f(p); 
} 
+0

未聲明mutable的lambda具有函數調用操作符聲明const。因此,通過拷貝捕獲的名稱在lambda體內是const的。因此,可能的解決方案是:1.通過引用捕獲,2.使用const_iterator或者3.使用可變的lambda(如果你確實需要改變迭代器,但不想修改原始的v) – JoergB

1

因爲f需要一個不帶參數的函數,但是lambda具有一個int參數。

+1

仍然不能使用'std :: function :: iterator(int)>' –

+0

查看mfontanini的回答(以及我的評論) – JoergB

2

如你是按值捕獲,捕獲vector(以及相關的迭代器)是const。如果你想要它是可變的,你需要改變lambda:

auto p = [=] (int n) mutable { 
    return std::find(v.begin(), v.end(), n); 
}; 
+0

+1,不知道捕獲價值意味着「外部世界是不變的」。 – mfontanini

+0

@mfontanini:實際上它的含義不止於此:它意味着即使在lambda封閉中捕獲的值的副本也是「const」。除非你使lambda爲'mutable',否則生成的調用操作符具有'const'限定符。 –

相關問題