std :: find_if в мультикарте возвращает ошибку с функтором - PullRequest
0 голосов
/ 15 мая 2018

В следующем фрагменте кода я пытаюсь найти в мультикарте значения, равные значению myPairA.second, которые соответствуют int f = 0. Однако в алгоритме STL std :: find_if это выдает ошибку:

 /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 создает ошибку) См. 2-ую версию ниже

#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;
}

выдает ошибку no viable overloaded '=' в строке, где std ::find_if is.

1 Ответ

0 голосов
/ 16 мая 2018

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 .Я решил опубликовать ответ, чтобы показать фиксированный код и, кроме того, как его можно упростить, используя инициализацию фигурных скобок, лямбда, 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;
}
...