2014-02-23 18 views
0

我目前正試圖在向量V中找到一個元素。 但我得到了很多錯誤。find_if的Lambda表達式

布爾VNS ::除去(常量主機名&名){ ^ 在文件從/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/include/c++/algorithm:62:0包括, 從vns.cc:2:.....

bool VNS::remove(const HostName& name){ 
     auto it=find_if(v.begin(),v.end(),[](const HostName& a, const HostName& b){return a==b;}); 
     //code that will remove the elem. 
     if(it!=v.end()){ 
      return true; 
     }else{ 
      return false; 
     } 
    } 
HeaderFile: 
class VNS:public NameServerInterface{ 
    public: 
     /* 
     * Insert a name/address pair. Does not check if the name 
     * or address already exists. 
     */ 
     virtual void insert(const HostName&, const IPAddress&); 

     /* 
     * Remove the pair with the specified host name. Returns true 
     * if the host name existed and the pair was removed, false 
     * otherwise. 
     */ 
     virtual bool remove(const HostName&); 

     /* 
     * Find the IP address for the specified host name. Returns 
     * NON_EXISTING_ADDRESS if the host name wasn't in the name 
     * server. 
     */ 
     virtual IPAddress lookup(const HostName&) const; 

    private: 
     std::vector<std::pair<HostName,IPAddress> > v; 
}; 

接口:

/* 
* Interface NameServerInterface -- all name server implementations must 
* implement this interface. 
*/ 
#ifndef NAME_SERVER_INTERFACE_H 
#define NAME_SERVER_INTERFACE_H 

#include <string> 

using HostName = std::string; 
using IPAddress = unsigned int; 
const IPAddress NON_EXISTING_ADDRESS = 0; 

class NameServerInterface { 
public: 
    virtual ~NameServerInterface() = default; 

    /* 
    * Insert a name/address pair. Does not check if the name 
    * or address already exists. 
    */ 
    virtual void insert(const HostName&, const IPAddress&) = 0; 

    /* 
    * Remove the pair with the specified host name. Returns true 
    * if the host name existed and the pair was removed, false 
    * otherwise. 
    */ 
    virtual bool remove(const HostName&) = 0; 

    /* 
    * Find the IP address for the specified host name. Returns 
    * NON_EXISTING_ADDRESS if the host name wasn't in the name 
    * server. 
    */ 
    virtual IPAddress lookup(const HostName&) const = 0; 
}; 

#endif 

我拉姆達EXP有兩個參數。編譯器將如何知道如何用正確的值替換它們。

+2

你期望'std :: find_if'作爲值傳入嗎? – chris

回答

2

std::find_if預計一元謂詞。你是傳遞一個二進制之一:

auto it=find_if(v.begin(),v.end(), 
       [](const HostName& a, const HostName& b){return a==b;}); 

這可不行。看起來這是你真正想要的:

auto it = std::find(v.begin(),v.end(), name); 
+0

但是,如果我有一元謂詞,我怎麼能比較兩件事? – user2975699

+0

@ user2975699只需使用'std :: find',如上所示。 – juanchopanza

+0

@ user2975699,你基本上正在做'std :: find'循環中的東西。它使用'=='來比較它所在的對象和它正在尋找的對象。如果它有幫助,你可以查看'std :: find' [here](http://en.cppreference.com/w/cpp/algorithm/find)的示例實現,看看它爲你自己做了什麼。 – chris

0

find_if你應該通過一個「上游」,即取一個參數和返回true/false功能。

[&](const HostName& a){return a==name;} 

更換您的lambda作爲您期望應該工作。

也就是說其他注意但是你可以把這個字符串傳給find代替謂詞來find_if因爲find使用operator==反正。

1

您不需要使用std::find_if。它是足夠使用std::find

變化thsi聲明

auto it=find_if(v.begin(),v.end(),[](const HostName& a, const HostName& b){return a==b;}); 

auto it=find(v.begin(),v.end(), name); 

編輯:我很抱歉。我沒有看到你所定義的向量作爲

std::vector<std::pair<HostName,IPAddress> > v; 

在這種情況下,你確實需要使用std::find_if與lambda表達式

auto it=find_if(v.begin(), v.end(), 
       [&](const std::pair<HostName,IPAddress>& a) { return a.first == name; }); 

另外,作爲成員函數remove具有返回類型bool我會建議給使用算法的std::find_if

例如std::any_of 代替

bool VNS::remove(const HostName &name) 
{ 
    return any_of(v.begin(), v.end(), 
        [&](const std::pair<HostName,IPAddress>& a) { return a.first == name; });  
} 

但如果你需要的目標迭代函數內部則的確是更好地使用std::find_if

還要考慮到,如果你確實是從載體取出一個元素,你可能不是

後寫
if(it!=v.end()){ 
     return true; 
    }else{ 
     return false; 
    } 

有效的代碼將

bool found = it != v.end(); 
if (found) 
{ 
    // removing the element 
} 

return found; 

的問題是,你提供了一個令人困惑的EXA :)

2

您的錯誤消息轉錄錯過了最有趣的部分:錯誤消息!

然而,問題似乎顯而易見:find_if功能只需要一個參數,所以你需要捕獲name,這是什麼[]是:

auto it=find_if(v.begin(),v.end(), 
    [&name](const HostName& a){return a==name;}); 

reference page介紹lambda表達式相當不錯。

+0

你能解釋一下[&名字]的含義嗎? 如果我有一個以上的arg func。我應該寫[[&name,&other] – user2975699

+0

@ user2975699:好的:這是捕獲列表。這意味着來自外部作用域的'name'將在lambda中可用,並具有相同的名稱。你可以通過'[name]'將值複製到lambda或'[&name]'中以便通過引用來獲取它,而不需要複製它。如果您通過參考採集,請注意您的拉姆達壽命不會超過捕獲的值。 – rodrigo

+0

沒有文檔。在演講中只聽說過它。 – user2975699