用于修复库代码中出现的编译错误的方法

Method for fixing compilation errors appearing in library code

本文关键字:编译 错误 方法 代码 用于      更新时间:2023-10-16

我正在尝试修复上一个编译错误,但遇到了这样一种情况:错误所指的行不在我编写的任何代码中,而是在其他标准库中。

显然,这个问题是由I正在做的事情引起的(例如,某个文件中的语法)。然而,无法知道我的代码中的哪一行正在调用导致错误的函数。回溯并没有更好地工作,因为函数可以从我的代码中被调用任意次数。

像这样的东西:。。。

template<class _InIt,
    class _Ty> inline
    _InIt _Find(_InIt _First, _InIt _Last, const _Ty& _Val, false_type)
    {   // find first matching _Val
    for (; _First != _Last; ++_First)
        if (*_First == _Val)
            break;
    return (_First);
    }

只是没有告诉我如何继续。

我知道,如果我能以某种方式在编译过程中后退一步,找到代码的最后一行,我可能会推断出这个问题。(我试图增加编译器输出的日志详细程度,但它没有提供任何有用的信息)。

调试此类问题的最佳方法是什么?是否有一种方法可以像使用标准调试器一样逐步完成编译过程,或者采用其他标准方法来解决问题?或者这是一件必须逐一处理的事情。

作为参考,我使用的是带有boost 1.59.0和sfml 2.3.2作为依赖项的VS2013。我正在处理的具体错误是徐蒂利,但我希望能有一些更全面的见解。

以下是完整的错误消息:

Error 4 error C2678: binary '==' : no operator found which takes a
left-hand operand of type
'std::map<std::string,int,std::less<_Kty>,std::allocator<std::pair<const
_Kty,_Ty>>>' (or there is no acceptable conversion)     c:program files (x86)microsoft visual studio 12.0vcincludexutility 3026 1 Engine

提前谢谢。

从您显示的错误消息部分来看,我希望"sane"代码是这样的:

#include <map>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
using Map = map<string, int>;
int main() {
    vector<Map> maps;
    Map target { { "one", 1 }, { "two", 2 } };
    auto match = std::find(maps.begin(), maps.end(), target);
}

您有一个错误的事实,很可能表明您把"target"参数搞砸了。例如:

auto match = std::find(maps.begin(), maps.end(), "one");

中的结果

error: invalid operands to binary expression ('std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > >' and 'const char *')
       { return *__it == _M_value; }

这是针对GCC/libstdc++的,它将此搜索的实现委托给find_if,因此细节不同)。

您可以在完整的错误消息中看到"堆栈":

clang++-3.6   -DNDEBUG -std=c++14 -Wall -pedantic  -g -O3 -isystem /home/sehe/custom/nonius/include -isystem /home/sehe/custom/boost_1_60_0 -isystem /usr/include/python2.7 -I /tmp/autobahn-cpp/ -pthread -march=native -L /home/sehe/custom/boost_1_60_0/stage/lib/ -Wl,-rpath,/home/sehe/custom/boost_1_60_0/stage/lib  test.cpp   -o test
test.cpp:14:10: warning: unused variable 'match' [-Wunused-variable]
    auto match = std::find(maps.begin(), maps.end(), "one");
        ^
In file included from test.cpp:1:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/map:60:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:63:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_algobase.h:71:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/predefined_ops.h:194:17: error: invalid operands to binary expression ('std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > >' and 'const char *')
        { return *__it == _M_value; }
                ~~~~~ ^  ~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_algo.h:120:8: note: in instantiation of function template specialization '__gnu_cxx::__ops::_Iter_equals_val<char const[4]>::operator()<__gnu_cxx::__normal_iterator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > *, std::vector<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > > > > >' requested here
        if (__pred(__first))
            ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_algo.h:161:14: note: in instantiation of function template specialization 'std::__find_if<__gnu_cxx::__normal_iterator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > *, std::vector<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > > > >, __gnu_cxx::__ops::_Iter_equals_val<char const[4]> >' requested here
    return __find_if(__first, __last, __pred,
            ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_algo.h:3790:19: note: in instantiation of function template specialization 'std::__find_if<__gnu_cxx::__normal_iterator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > *, std::vector<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > > > >, __gnu_cxx::__ops::_Iter_equals_val<char const[4]> >' requested here
    return std::__find_if(__first, __last,
                ^
test.cpp:14:23: note: in instantiation of function template specialization 'std::find<__gnu_cxx::__normal_iterator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > *, std::vector<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > > > > >, char [4]>' requested here
    auto match = std::find(maps.begin(), maps.end(), "one");
                    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_pair.h:214:5: note: candidate template ignored: could not match 'pair' against 'map'
    operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_iterator.h:292:5: note: candidate template ignored: could not match 'reverse_iterator' against 'map'
    operator==(const reverse_iterator<_Iterator>& __x,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_iterator.h:342:5: note: candidate template ignored: could not match 'reverse_iterator' against 'map'
    operator==(const reverse_iterator<_IteratorL>& __x,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_iterator.h:820:5: note: candidate template ignored: could not match '__normal_iterator' against 'map'
    operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_iterator.h:827:5: note: candidate template ignored: could not match '__normal_iterator' against 'map'
    operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_iterator.h:1065:5: note: candidate template ignored: could not match 'move_iterator' against 'map'
    operator==(const move_iterator<_IteratorL>& __x,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_iterator.h:1071:5: note: candidate template ignored: could not match 'move_iterator' against 'map'
    operator==(const move_iterator<_Iterator>& __x,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/ext/new_allocator.h:139:5: note: candidate template ignored: could not match 'new_allocator' against 'map'
    operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/allocator.h:128:5: note: candidate template ignored: could not match 'allocator' against 'map'
    operator==(const allocator<_T1>&, const allocator<_T2>&)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/allocator.h:134:5: note: candidate template ignored: could not match 'allocator' against 'map'
    operator==(const allocator<_Tp>&, const allocator<_Tp>&)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:324:5: note: candidate template ignored: could not match '_Rb_tree_iterator' against 'map'
    operator==(const _Rb_tree_iterator<_Val>& __x,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_tree.h:1273:5: note: candidate template ignored: could not match '_Rb_tree' against 'map'
    operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/postypes.h:216:5: note: candidate template ignored: could not match 'fpos' against 'map'
    operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/basic_string.h:4902:5: note: candidate template ignored: could not match 'basic_string' against 'map'
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/basic_string.h:4909:5: note: candidate template ignored: could not match 'basic_string' against 'map'
    operator==(const basic_string<_CharT>& __lhs,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/basic_string.h:4923:5: note: candidate template ignored: could not match 'const _CharT *' against 'std::map<std::__cxx11::basic_string<char>, int, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> > >'
    operator==(const _CharT* __lhs,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/basic_string.h:4935:5: note: candidate template ignored: could not match 'basic_string' against 'map'
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/array:240:5: note: candidate template ignored: could not match 'array' against 'map'
    operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/tuple:915:5: note: candidate template ignored: could not match 'tuple' against 'map'
    operator==(const tuple<_TElements...>& __t,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_map.h:1052:9: note: candidate template ignored: could not match 'map<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2, type-parameter-0-3>' against 'char const[4]'
        operator==(const map<_K1, _T1, _C1, _A1>&,
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_multimap.h:974:5: note: candidate template ignored: could not match 'multimap' against 'map'
    operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/stl_vector.h:1511:5: note: candidate template ignored: could not match 'vector' against 'map'
    operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/random.tcc:2030:5: note: candidate template ignored: could not match 'normal_distribution' against 'map'
    operator==(const std::normal_distribution<_RealType>& __d1,
    ^
1 warning and 1 error generated.
<builtin>: recipe for target 'test' failed
make: *** [test] Error 1

提示:

  • 通常最好只查看文档中代码的顶层调用(test.cpp中的find):http://en.cppreference.com/w/cpp/algorithm/find
  • 无视被拒绝的候选人。ADL的本质是,候选人的负荷显然不适用。只有当您需要调试库代码以找出您自己的operator==重载被拒绝的原因时,这才有用

开箱即用

如果我猜对了你的API滥用,这里有一个建议的解决方案:

在Coliru上直播

#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
using Map = map<string, int>;
int main() {
    vector<Map> maps;
    Map target { { "one", 1 }, { "two", 2 } };
    auto match = std::find_if(maps.begin(), maps.end(), [](Map const& m) { return m.end() != m.find("one"); });
    if (match != maps.end()) {
        for (auto const& p : *match) {
            std::cout << p.first << " -> " << p.second << "n";
        }
    }
}

当然,假设样本中的maps为空,则不会打印任何内容。