我遇到了在调试模式下编译一些使用std :: lower_bound()函数和比较运算符的代码的麻烦。
我已在以下附加的小代码段中隔离了错误:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct SPippo
{
SPippo(string rsName, int rnValue);
static const bool compareId(const SPippo& lhs, const int& rId){return lhs.iValue < rId;}
string sName;
int iValue;
};
SPippo::SPippo(string rsName, int riValue):
sName(rsName)
,iValue(riValue)
{
}
struct sOrd
{
const bool operator() (const SPippo& lhs, const int& rId) const {return SPippo::compareId(lhs, rId);}
const bool operator() (const int& rId, const SPippo& lhs) const {return SPippo::compareId(lhs, rId);}
};
int main()
{
vector<SPippo> vecPippo;
vecPippo.push_back(SPippo("Minnie", 1));
vecPippo.push_back(SPippo("Paperino", 2));
vecPippo.push_back(SPippo("Pippo", 3));
vecPippo.push_back(SPippo("Topolino", 4));
vector<SPippo>::const_iterator cItLowerBound = std::lower_bound(vecPippo.begin(), vecPippo.end(), 2, sOrd());
return 0;
}
我正在使用VS2008进行编译:使用发布配置时一切正常。相反,在调试模式下,我收到以下错误:
1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(346) : error C2664: 'const bool sOrd::operator ()(const int &,const SPippo &) const' : cannot convert parameter 1 from 'SPippo' to 'const int &'
1> Reason: cannot convert from 'SPippo' to 'const int'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(1699) : see reference to function template instantiation 'bool std::_Debug_lt_pred<_Pr,SPippo,SPippo>(_Pr,_Ty1 &,_Ty2 &,const wchar_t *,unsigned int)' being compiled
1> with
1> [
1> _Pr=sOrd,
1> _Ty1=SPippo,
1> _Ty2=SPippo
1> ]
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(1709) : see reference to function template instantiation 'void std::_Debug_order_single2<_InIt,_Pr>(_FwdIt,_FwdIt,_Pr,bool,const wchar_t *,unsigned int,std::forward_iterator_tag)' being compiled
1> with
1> [
1> _InIt=std::_Vector_iterator<SPippo,std::allocator<SPippo>>,
1> _Pr=sOrd,
1> _FwdIt=std::_Vector_iterator<SPippo,std::allocator<SPippo>>
1> ]
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\algorithm(2290) : see reference to function template instantiation 'void std::_Debug_order_single<_FwdIt,_Pr>(_InIt,_InIt,_Pr,bool,const wchar_t *,unsigned int)' being compiled
1> with
1> [
1> _FwdIt=std::_Vector_iterator<SPippo,std::allocator<SPippo>>,
1> _Pr=sOrd,
1> _InIt=std::_Vector_iterator<SPippo,std::allocator<SPippo>>
1> ]
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\algorithm(2314) : see reference to function template instantiation '_FwdIt std::_Lower_bound<std::_Vector_iterator<_Ty,_Alloc>,int,__w64 int,_Pr>(_FwdIt,_FwdIt,const int &,_Pr,_Diff *)' being compiled
1> with
1> [
1> _FwdIt=std::_Vector_iterator<SPippo,std::allocator<SPippo>>,
1> _Ty=SPippo,
1> _Alloc=std::allocator<SPippo>,
1> _Pr=sOrd,
1> _Diff=__w64 int
1> ]
1> c:\users\cgab\documents\visual studio 2008\projects\sweettest\sweettest\main.cpp(42) : see reference to function template instantiation '_FwdIt std::lower_bound<std::_Vector_iterator<_Ty,_Alloc>,int,sOrd>(_FwdIt,_FwdIt,const int &,_Pr)' being compiled
1> with
1> [
1> _FwdIt=std::_Vector_iterator<SPippo,std::allocator<SPippo>>,
1> _Ty=SPippo,
1> _Alloc=std::allocator<SPippo>,
1> _Pr=sOrd
1> ]
1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(348) : error C2664: 'const bool sOrd::operator ()(const int &,const SPippo &) const' : cannot convert parameter 1 from 'SPippo' to 'const int &'
1> Reason: cannot convert from 'SPippo' to 'const int'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>Build log was saved at "file://c:\Users\cgab\Documents\Visual Studio 2008\Projects\SweetTest\SweetTest\Debug\BuildLog.htm"
1>SweetTest - 2 error(s), 0 warning(s)
使用VS2015或更高版本时,代码在调试模式下编译也很好。 鉴于我被迫使用VS2008作为我的项目,你认为有没有办法解决这个问题而不放弃使用lower_bound()?
提前感谢您的协助!
我认为问题在于VS2008在xutility中使用的代码。实际上,错误指向以下摘录:
template<class _Pr, class _Ty1, class _Ty2> inline
bool __CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, const _Ty1& _Left, const _Ty2& _Right,
const wchar_t *_Where, unsigned int _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
if (!_Pred(_Left, _Right))
return (false);
else if (_Pred(_Right, _Left))
_DEBUG_ERROR2("invalid operator<", _Where, _Line);
return (true);
因此,测试了一个 Pred 函数,反转了参数的顺序。但是,如果谓词接受相同类型的参数,则此方法有效,否则不行!
由于_ITERATOR_DEBUG_LEVEL的默认设置,在 C:\ Program Files(x86)\ Microsoft Visual Studio 10.0 \ VC \ include \ yvals.h <中定义,因此VS2010中源代码xutility的这一特定部分未执行。 / em>的。 这可能解释了为什么代码在VS2008以外的其他版本的VS中编译。
答案 0 :(得分:0)
如果其他人偶然发现这种情况,解决此问题的“黑客”是禁用相应编译单元的迭代器调试。如果放在#include
指令之前,下面的代码会剪切:
#if defined(_MSC_VER) && defined(_DEBUG) && _MSC_VER <= 1500
#define _HAS_ITERATOR_DEBUGGING 0
#endif