const_iterator, find_if и bind2nd: нет совпадения для вызова ошибки

Я пытаюсь использовать find_if, чтобы найти ключ на карте по его значению. Но я не могу скомпилировать код:

struct IsCurrency : binary_function<pair<const Bill::CodeCurrency, string>, string, bool> {
bool isCurrency(const pair<const Bill::CodeCurrency, string>& element, const string& expected) const {
return element.second == expected;
}
};

string currency = "RUB";
map<Bill::CodeCurrency, string>::const_iterator my_currency = find_if(Bill::currency_code_map().begin(), Bill::currency_code_map().end(), bind2nd(IsCurrency(), currency));  /// <--- ERROR IS HERE

Bill::CodeCurrency это перечисление.

ошибка:

/usr/include/c++/4.7/bits/stl_algo.h:4490:41:   required from ‘_IIter std::find_if(_IIter, _IIter, _Predicate) [with _IIter = std::_Rb_tree_const_iterator<std::pair<const Bill::CodeCurrency, std::basic_string<char> > >; _Predicate = std::binder2nd<IsCurrency>]’
../src/money_acceptor/itl_bill_acceptor.cpp:182:121:   required from here
/usr/include/c++/4.7/backward/binders.h:155:29: error: no match for call to ‘(const IsCurrency) (const first_argument_type&, const second_argument_type&)’

Не могли бы вы помочь мне определить, в чем здесь ошибка?

0

Решение

Как описано в моем комментарии, реальная проблема заключается в том, что предикат, предоставленный find_if требуется иметь operator(), а не какая-то функция с именем, похожим на имя класса.

Версия C ++ 03:

#include <map>
#include <functional>
#include <string>
#include <algorithm>

namespace Bill
{
enum CodeCurrency
{
A, B, C
};

typedef std::map<CodeCurrency, std::string> currency_code_map_t;
currency_code_map_t const& currency_code_map()
{
static currency_code_map_t m;
return m;
}
}

struct IsCurrency
: std::binary_function< Bill::currency_code_map_t::value_type, std::string,
bool >
{
bool operator()(Bill::currency_code_map_t::value_type const& element,
std::string const& expected) const
{
return element.second == expected;
}
};

int main()
{
std::string currency = "RUB";
Bill::currency_code_map_t::const_iterator my_currency =
std::find_if( Bill::currency_code_map().begin(),
Bill::currency_code_map().end(),
bind2nd(IsCurrency(), currency) );
}

C ++ 11 версия:

#include <map>
#include <functional>
#include <string>
#include <algorithm>

namespace Bill
{
enum CodeCurrency
{
A, B, C
};

typedef std::map<CodeCurrency, std::string> currency_code_map_t;
currency_code_map_t const& currency_code_map()
{
static currency_code_map_t m;
return m;
}
}

int main()
{
std::string currency = "RUB";
auto check = [&currency](Bill::currency_code_map_t::value_type const& element)
{ return element.second == currency; };
auto my_currency =
std::find_if( Bill::currency_code_map().cbegin(),
Bill::currency_code_map().cend(),
check );
}

Обратите внимание, что этот алгоритм O (N). Вы можете рассмотреть возможность использования чего-то вроде boost::bimap если вам нужно часто находить элементы, которые могут быть O (logN).

0

Другие решения

замещать bool isCurrency(...) от bool operator () (...) сделать вашу структуру вызываемой.

0

По вопросам рекламы [email protected]