首页 > 解决方案 > 尝试通过放入向量对地图值进行排序时出现令人讨厌的难以理解的错误

问题描述

我有一个有 的WordEntryunordered_map<string, int>,我想存储每个单词的频率。我可以这样做,但我也想向用户显示前 5 个单词和后 5 个单词。为此,我必须进行排序。但是,我遇到了一个非常糟糕、令人讨厌的错误,这与您的正常 c++ 异常不同。我不确定包括它是否会有很大帮助,因为它相当长。这是我的wordentry.h

#ifndef WORDENTRY_H
#define WORDENTRY_H
#include "node.h"
#include "bst.h"
#include <vector>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;

template <class T>
class WordEntry
{
public:
    int retrieveWordFreq(Node<T> *);
    void collectWords(T data);
    void getTop5();
    void getBot5();
    unordered_map<T, int> freqs;

private:
    int freq = 0;
    bool sortByVal( pair<string, int> &a,  pair<string, int> &b);
};

template <class T>
int WordEntry<T>::retrieveWordFreq(Node<T> *word)
{
}

template <class T>
void WordEntry<T>::getTop5()
{
    vector<pair<string, int>> vec;

    // copy key-value pairs from the map to the vector
    unordered_map<string, int>::iterator it2;
    for (it2 = freqs.begin(); it2 != freqs.end(); it2++)
    {
        vec.push_back(make_pair(it2->first, it2->second));
    }

    // // sort the vector by increasing order of its pair's second value
    sort(vec.begin(), vec.end(), sortByVal);

    for (int i = vec.size() - 1; i > vec.size() - 6; i--)
    {
        cout << vec[i].first << ": " << vec[i].second << endl;
    }
}

template <class T>
void WordEntry<T>::getBot5()
{
    vector<pair<string, int>> vec;

     for (auto& it : freqs) {
        vec.push_back(it);
    }

    
    sort(vec.begin(), vec.end(), sortByVal);

    for (int i = 0; i < 6; i++)
    {
        cout << vec[i].first << ": " << vec[i].second << endl;
    }
}

template <class T>
void WordEntry<T>::collectWords(T val)
{
    freqs[val]++;
}

template <class T>
bool WordEntry<T>::sortByVal(pair<string, int> &a,  pair<string, int> &b)
{
    return (a.second < b.second);
}
#endif

和我的主要


#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_set>
#include "bst.h"
#include "wordentry.h"


using namespace std;

int main()
{
    fstream file;
    string word, filename;

    BST<string> wordTree; 
    unordered_set<string> set; 
    WordEntry<string> words; 

    filename = "file.txt";
    file.open(filename.c_str());

    
    while (file >> word)
    {
        wordTree.insert(word); 
        words.collectWords(word); 
    } 
    
    cout << "Words amount: " << wordTree.length() << "\n";
    cout << "Unique Words amount: " << set.size() << "\n"; 
    
    words.getBot5(); 

    int choice; 
    
    cout << "What do you want to do?\n1. Enter a word and find it's frequency\n2.Output frequency analysis to a file\n"; 
    cin >> choice; 
    if (choice == 1) {
        string word; 
        cout << "Enter the word you want the frequency of \n"; 
        cin >> word; 
        for (auto x : words.freqs)
        {
            if (x.first == word)
            {
                cout << x.second; 
            }
        }
    }
    else if (choice == 2)
    {
        ofstream outfile ("output.txt"); 
        outfile << "Words amount: " << wordTree.length() << "\n";
        outfile << "Unique Words amount: " << set.size() << "\n"; 
    }
    
    
   return 0; 
    
}

words.getBot5();是罪魁祸首,这意味着我的实施是错误的,但我不知道为什么。我只是将密钥对复制到向量并进行排序。

编辑:这是错误

In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algobase.h:71:0,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\char_traits.h:39,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ios:40,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\ostream:38,
                 from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\iostream:39,
                 from driver.cpp:1:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h: In instantiation of 
'constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > 
>; _Iterator2 = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1844:14:   required from 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; 
_Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1882:25:   required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1968:31:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4739:18:   required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]'
wordentry.h:62:9:   required from 'void WordEntry<T>::getBot5() [with T = std::__cxx11::basic_string<char>]'
driver.cpp:34:19:   required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h:123:18: error: must use '.*' or '->*' to call pointer-to-member function in '((__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp (...)', e.g. '(... ->* ((__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp) (...)'
         { return bool(_M_comp(*__it1, *__it2)); }
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h: In instantiation of 
'bool __gnu_cxx::__ops::_Iter_comp_val<_Compare>::operator()(_Iterator, _Value&) [with _Iterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, 
int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Value = std::pair<std::__cxx11::basic_string<char>, int>; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_heap.h:129:48:   required from 'void std::__push_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with 
_RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Distance = int; _Tp = std::pair<std::__cxx11::basic_string<char>, int>; _Compare = __gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_heap.h:230:23:   required from 'void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; 
_Distance = int; _Tp = std::pair<std::__cxx11::basic_string<char>, int>; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_heap.h:335:22:   required from 'void std::__make_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1669:23:   required from 'void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1930:25:   required from 'void std::__partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, 
std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1945:27:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Size = int; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:1965:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_algo.h:4739:18:   required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char>, int>*, std::vector<std::pair<std::__cxx11::basic_string<char>, int> > >; _Compare = bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)]'
wordentry.h:62:9:   required from 'void WordEntry<T>::getBot5() [with T = std::__cxx11::basic_string<char>]'
driver.cpp:34:19:   required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\predefined_ops.h:144:11: error: must use '.*' or '->*' to call pointer-to-member function in '((__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp (...)', e.g. '(... ->* ((__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>*)this)->__gnu_cxx::__ops::_Iter_comp_val<bool (WordEntry<std::__cxx11::basic_string<char> >::*)(std::pair<std::__cxx11::basic_string<char>, int>&, std::pair<std::__cxx11::basic_string<char>, int>&)>::_M_comp) (...)'
  { return bool(_M_comp(*__it, __val)); }
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~

标签: c++

解决方案


你需要做一些不同的事情。

首先,您必须static像这样制作比较器:

template <class T>
class WordEntry
{
public:
//    int retrieveWordFreq(Node<T> *);
    void collectWords(T data);
    void getTop5();
    void getBot5();
    unordered_map<T, int> freqs;

private:
    int freq = 0;
   static bool sortByVal( pair<string, int> &a,  pair<string, int> &b); // static
};

因为普通成员函数指针比静态成员函数更复杂,因为它们需要一个对象来操作。

其次,您必须使用其限定名称来引用它:

sort(vec.begin(), vec.end(), WordEntry<T>::sortByVal); // qualified name

推荐阅读