如何读取库错误 C++

How to read library errors c++

我正在编译一个 c++ 项目来模拟一种语言随着时间的推移从一小部分引入的单词中发生变化,它工作正常,直到它无法编译并输出库错误 garblygoook。通常这不是问题我可以自己调试正常错误,但错误消息非常不可读(至少对于初学者而言)它似乎是一些奇怪的库错误,可能与标准算法库有关。我需要一些帮助来解码它并了解出了什么问题。将来阅读这些奇怪消息的任何其他提示和技巧将不胜感激。注意:我在 windows 上使用 mingw,使用 c++17。

error message from compiler

我认为可能导致问题的代码(来自 wordmod.cpp):

std::vector<int> WordMod::CreateChangedMask(std::string Word){
std::vector<int> changedCharsMask;
for( int currCharPos = 0; currCharPos < Word.length()-1; currCharPos++){
    int maskNum = rand() % 100 + 1;
    if(std::find(VowelChars.begin(), VowelChars.end(), Word[currCharPos]) != VowelChars.end()){
        changedCharsMask.push_back(0);
    }
    else if (maskNum <= PERCENT_CHANGE){
        changedCharsMask.push_back(1);
    }
    else{
        changedCharsMask.push_back(0);
    }

}

full github code

您的问题在 wordMod.cpp 文件的第 70 行。具体这个功能:

std::vector<std::shared_ptr<Word>> WordMod::DeleteRepeats(std::vector<std::shared_ptr<Word>> wordlist){
    for(int currword = 0; currword < wordlist.size(); currword++){
        wordlist.erase(std::remove(wordlist.begin(), wordlist.end(), wordlist[currword]->get_word()), wordlist.end());
    }
    return wordlist;
}

std::remove 调用中,我假设您的意图是删除单词与从 wordlist[currword]->get_word() 获得的单词相同的每个元素。标准库通过遍历 wordlist.begin()wordlist.end() 之间的每个元素并检查它们是否等于 wordlist[currword]->get_word().

来做到这一点

wordlist 不是 std::string 对象的向量(我假设是 wordlist[currword]->get_word() returns),它是 std::shared_ptr<Word> 意味着标准库会尝试检查 std::shared_ptr<Word> 是否等于 std::string。并且库不知道如何检查是否相等。

简单的解决方法是将函数更改为:

std::vector<std::shared_ptr<Word>> WordMod::DeleteRepeats(std::vector<std::shared_ptr<Word>> wordlist){
    for(int currword = 0; currword < wordlist.size(); currword++){
        wordlist.erase(std::remove_if(wordlist.begin(), wordlist.end(), [&](std::shared_ptr<Word> w){
            return wordlist[currword]->get_word() == w->get_word();
        }), wordlist.end());
    }
    return wordlist;
}

编辑:

我还注意到这个函数实际上只会删除向量中的每个元素,因为您也删除了您正在比较的元素。此函数的第二个版本如下所示:

std::vector<std::shared_ptr<Word>> WordMod::DeleteRepeats(std::vector<std::shared_ptr<Word>> wordlist){
    for(int currword = 0; currword < wordlist.size(); currword++){
        if(currword != wordlist.size()-1){
            wordlist.erase(std::remove_if(wordlist.begin()+currword+1, wordlist.end(), [&](std::shared_ptr<Word> w){
                return wordlist[currword]->get_word() == w->get_word();
            }), wordlist.end());
        }
    }
    return wordlist;
}

此版本的函数只会删除您正在比较的那个之后的元素

编辑2:

为了清楚起见,我通过检查所有错误中的第一个错误从错误中得到了它们:

In file included from c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\stl_algobase.h:71,
                 from c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\char_traits.h:39,
                 from c:\mingw\lib\gcc\mingw32.2.0\include\c++\string:40,
                 from wordMod.hpp:6,
                 from wordMod.cpp:1:
c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_equals_val<_Value>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<std::shared_ptr<Word>*, std::vector<std::shared_ptr<Word> > >; _Value = const std::__cxx11::basic_string<char>]':      
c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\stl_algo.h:869:13:   required from '_ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<std::shared_ptr<Word>*, std::vector<std::shared_ptr<Word> > >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const std::__cxx11::basic_string<char> >]'
c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\stl_algo.h:906:30:   required from '_FIter std::remove(_FIter, _FIter, const _Tp&) [with _FIter = __gnu_cxx::__normal_iterator<std::shared_ptr<Word>*, std::vector<std::shared_ptr<Word> > >; _Tp = std::__cxx11::basic_string<char>]'
wordMod.cpp:70:100:   required from here
c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\predefined_ops.h:241:17: error: no match for 'operator==' (operand types are 'std::shared_ptr<Word>' and 'const std::__cxx11::basic_string<char>')
  241 |  { return *__it == _M_value; }
      |  

wordMod.cpp:70:100: required from here 告诉我问题出在 wordMod.cpp 文件的行 70 和行

c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\stl_algo.h:906:30:   required from '_FIter std::remove(_FIter, _FIter, const _Tp&) [with _FIter = __gnu_cxx::__normal_iterator<std::shared_ptr<Word>*, std::vector<std::shared_ptr<Word> > >; _Tp = std::__cxx11::basic_string<char>]'

告诉我问题出在该线路上的 std::remove 呼叫中。

c++ 编译器倾向于吐出又长又奇怪又复杂的错误,但解决它们的方法是只看第一个错误,修复它,然后在很多时候修复它一个得到修复,其他的也得到修复。一次拿一个

我通常从顶部开始查找我列出的文件(通常查找 *.cpp)。

这指向这一行:

c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\stl_algo.h:906:30:   required from '_FIter std::remove(_FIter, _FIter, const _Tp&) [with _FIter = __gnu_cxx::__normal_iterator<std::shared_ptr<Word>*, std::vector<std::shared_ptr<Word> > >; _Tp = std::__cxx11::basic_string<char>]'
wordMod.cpp:70:100:   required from here

那么让我们来看看 wordMod.cpp:70:

std::vector<std::shared_ptr<Word>> WordMod::DeleteRepeats(std::vector<std::shared_ptr<Word>> wordlist){
    for(int currword = 0; currword < wordlist.size(); currword++){
        wordlist.erase(std::remove(wordlist.begin(), wordlist.end(), wordlist[currword]->get_word()), wordlist.end()); // this line is 70
    }
    return wordlist;
}

快速浏览一下这段代码可能看起来没问题,所以看看下一条错误消息是什么:

c:\mingw\lib\gcc\mingw32.2.0\include\c++\bits\predefined_ops.h:241:17: error: no match for 'operator==' (operand types are 'std::shared_ptr<Word>' and 'const std::__cxx11::basic_string<char>')
  241 |  { return *__it == _M_value; }

所以你的代码要求 operator==std::shared_ptr<Word>const std::string 之间,这显然是错误的。

在最后一步中,查看您要尝试执行的操作的详细信息:

  • 您正在移除向量的元素
  • 其中包含 shared_ptroperator== 的左参数)
  • 并且您正在搜索类型为 std::string 的值,因为这是 get_word() returns(operator== 的右参数)

所以现在问题应该很明显了。