multimap中的std :: find_if使用仿函数返回错误

时间:2018-05-15 20:32:52

标签: c++ stl functor

在下面的代码片段中,我尝试在multimap中查找等于myPairA.second值的值,这些值对应于int f = 0.但是在std :: find_if STL算法中,这显示错误:

 /usr/include/c++/5/bits/predefined_ops.h:234:30: error: no match for call to ‘(EqualFunctor<int>) (std::pair<const int, int>&)’
   { return bool(_M_pred(*__it)); }
                               ^`

 multimaps_2.cpp:12:10: note: candidate: bool EqualFunctor<T>::operator()(std::pair<const int, T*>) [with T = bool operator() (std::pair<const int, T*> myPair)

这是我的程序:(带有std :: find_if的行会产生错误) 请参阅下面的第二个版本

#include <iostream>
#include <algorithm>
#include <iterator>
#include <map>

template <typename T>
class EqualFunctor
{
    T *t_;
public:
    EqualFunctor(T *t) : t_(t) {}
    bool operator() (std::pair<const int, T*> myPair)
    { return myPair.second == t_; }    
};

int main()
{
    // h, i & j are duplicates of f and g
    int f = 0, g = 1,
        h = 0, i = 1, j = 1;

    // declare five pairs
    std::pair<const int, int> myPairA (1, f),
                              myPairB (2, g),
                              myPairC (3, h),
                              myPairD (4, i),
                              myPairE (5, j);

    std::multimap<int, int> myMultimap;

    // insert pairs above in multimap with the exception of myPairA

    myMultimap.insert(myPairB);
    myMultimap.insert(myPairC);
    myMultimap.insert(myPairD);
    myMultimap.insert(myPairE);

    std::multimap<int, int>::iterator it;

    // pointer to f = 0, since the EqualFunctor class accepts a pointer
    int *ptrMyPairA = &myPairA.second;

    // find in multimap the pair that is equal to f, ie myPairA.second
    // with the EqualFunctor class 
    // Problem is here
    it = std::find_if(myMultimap.begin(), myMultimap.end(),
              EqualFunctor<int>(ptrMyPairA));

    // print to screen 
    std::cout << (*it).second << std::endl;    
    return 0;
}

所需的输出是在屏幕上显示0,这对应于多图中第一次出现重复。 (myPairC.second等于int h = 0)

我已尝试阅读与此stackoverflow问题相关的其他帖子,但它并没有帮助我解决这个问题。 我的问题几乎与stackoverflow上的问题相同,但它仍然存在 没有帮助解决问题。 感谢

修改: 将std::pair<const int, int>更改为std::pair<const int, int*>仍然会出错:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <map>

template <typename T>
class EqualFunctor
{
    T *t_;
public:
    EqualFunctor(T *t) : t_(t) {}
    bool operator() (std::pair<const int, T*> myPair)
    { return myPair.second == t_; }    
};

int main()
{
    // h, i & j are duplicates of f and g
    int f = 0, g = 1,
        h = 0, i = 1, j = 1;

    int *ptrF = &f, *ptrG = &g,
        *ptrH = &h, *ptrI = &i, *ptrJ = &j;
    // declare five pairs 
    std::pair<const int, int*> myPairA (1, ptrF),
                               myPairB (2, ptrG),
                               myPairC (3, ptrH),
                               myPairD (4, ptrI),
                               myPairE (5, ptrJ);

    std::multimap<int, int> myMultimap;

    // insert pairs above in multimap with the exception of myPairA

    myMultimap.insert(myPairB);
    myMultimap.insert(myPairC);
    myMultimap.insert(myPairD);
    myMultimap.insert(myPairE);

    std::multimap<int, int>::iterator it;

    // find in multimap the pair that is equal to f, ie myPairA.second
    // with the EqualFunctor class 
    // Problem is here
    it = std::find_if(myMultimap.begin(), myMultimap.end(),
                      EqualFunctor<int>(myPairA.second));

    // print to screen 
    std::cout << (*it).second << std::endl;    
    return 0;
}

在std :: find_if所在的行上给出错误no viable overloaded '='

1 个答案:

答案 0 :(得分:2)

0x499602D2已经在评论中解释了问题,所以如果他在接受任何其他重播之前发布了答案,请等待。

The element type of the map isn't pair<const int, int*>, 
it's pair<const int, int> as you have written. 
Your functor takes the former which is why it doesn't work.

您可以在Wandbox上找到固定代码。我决定发布一个答案来展示固定代码,另外还有如何使用大括号初始化,lambda,auto和构造函数推导来简化代码:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <map>

template <typename K, typename V>
class EqualFunctor
{
    V t_;
public:
    EqualFunctor(V t) : t_(t) {}
    bool operator() (std::pair<K const, V> const& myPair)
    { return myPair.second == t_; }    
};

int main()
{
    // use C++17 constructor deduction
    auto const myPairA = std::pair(1, 0);

    auto const myMultimap = std::multimap<int,int>{ {2,1}, {3,0}, {4,1}, {5,1}};

    // find in multimap the pair that is equal to f, ie myPairA.second
    // with the EqualFunctor class 
    // Problem is here
    auto it = std::find_if(myMultimap.begin(), myMultimap.end(),
                      EqualFunctor<int,int>(myPairA.second));

    // print to screen 
    std::cout << it->second << std::endl;    

    // simpler with lambda
    it = std::find_if(myMultimap.begin(), myMultimap.end(),
                      [&myPairA](auto const& x) {return x.second == myPairA.second;} );

    // print to screen 
    std::cout << it->second << std::endl;    

    return 0;
}