find_if的Lambda表达式

时间:2014-02-23 18:05:06

标签: c++

我目前正在尝试在向量V中找到一个元素。 但我得到了很多错误。

bool VNS :: remove(const HostName& name){       ^ 在/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

我的lambda exp有两个参数。编译器将如何知道如何用正确的值替换它们。

4 个答案:

答案 0 :(得分:3)

您的错误消息转录错过了最有趣的部分:错误消息!

然而,问题似乎很明显:find_if函数只需要一个参数,因此您需要捕获name[]是什么:< / p>

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

reference page很好地解释了lambda。

答案 1 :(得分: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);

答案 2 :(得分: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::any_of 而不是std::find_if

例如

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;

问题是你提供了一个令人困惑的代码示例。:)

答案 3 :(得分:0)

find_if你应该传递一个“谓词”,即一个函数只需一个参数并返回true / false

替换你的lambda
[&](const HostName& a){return a==name;}

应该按预期工作。

如上所述,您可以将字符串传递给find而不是谓词find_if,因为find无论如何都会使用operator==