【问题标题】:const_iterator, find_if and bind2nd: no match for call to errorconst_iterator、find_if 和 bind2nd:错误调用不匹配
【发布时间】:2014-05-22 15:43:38
【问题描述】:

我尝试使用 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&)’

您能帮我确定这里的错误是什么吗?

【问题讨论】:

  • 1) 代码的格式很糟糕(我见过更糟糕的,但是 > 190 字符长的行?) 2) 使用已弃用的 StdLib 实体(例如 binary_function) 3)你的问题是isCurrency 应该是 operator() -> compiles then
  • 多一点上下文会很有用。例如,从您的示例中很难判断 Bill 是命名空间还是类。

标签: c++ templates const-iterator bind2nd


【解决方案1】:

正如我的评论中所描述的,实际问题是提供给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)。

【讨论】:

    【解决方案2】:

    bool isCurrency(...) 替换为bool operator () (...) 以使您的结构可调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多