В настоящее время я пытаюсь найти элемент в векторе 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
У моей лямбды exp есть два параметра. Как компилятор узнает, как он должен заменить их правильными значениями.
Ваша транскрипция сообщения об ошибке пропускает самую интересную часть: сообщение об ошибке!
Тем не менее проблема кажется очевидной: для функции find_if
нужен только один параметр, поэтому вам нужно find_if
name
, что для []
:
auto it=find_if(v.begin(),v.end(),
[&name](const HostName& a){return a==name;});
Эта справочная страница достаточно хорошо описывает лямбды.
name
из внешней области будет доступно внутри лямбды с тем же именем. Вы можете сделать [name]
чтобы скопировать значение в лямбду, или [&name]
чтобы получить его по ссылке, то есть без копирования. Если вы захватываете по ссылке, будьте осторожны, чтобы ваша лямбда не проживала дольше, чем зафиксированное значение.
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);
std::find
, как показано выше.
Вам не нужно использовать 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 );
EDIT: Мне очень жаль. Я не видел, что вы определили вектор как
std::vector<std::pair<HostName,IPAddress> > v;
В этом случае вам действительно нужно использовать std::find_if
с выражением лямбда
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;
Проблема в том, что вы представили запутанный пример кода. :)
to find_if
вы должны передать "предикат", то есть функцию, принимающую один единственный параметр и возвращающий true
/false
.
Замена лямбды
[&](const HostName& a){return a==name;}
должен работать так, как вы ожидаете.
Тем не менее, как указано другим, вы можете просто передать строку, чтобы find
вместо предиката find_if
потому что find
использует operator==
любом случае.
std::find_if
в качестве значений?