我正在尝试编译一个小型 COM dll(使用 Visual Studio 2008 Pro),它在发布中编译得很好,但是当我尝试在调试中编译它时,我收到编译错误:
错误 C2664: 'bool (MyClass &, double)': 无法转换参数 2
从“MyClass”到“double”。
现在这个错误来自我执行此操作的代码中的一行(请注意 someValueThatIsADouble 的类型为 double):
std::vector<MyClass>::iterator iter = std::lower_bound(MyVector.begin(), MyVector.end(), someValueThatIsADouble, less);
并且 less 函数是这样定义的:
bool less(MyClass& a, double b);
我不明白为什么会收到此错误,如果有一个好的出现此错误的原因,为什么我只能在调试中得到它(而不是在发布中得到它)?该dll在Release中编译时运行良好并且不会崩溃。另外,我检查过,没有 #ifdef DEBUG
或类似的东西可以更改在调试和发布中编译的代码。
编辑:
我自己没有编写代码,这是一个我不太了解的算法,所以我不知道 double 值应该代表什么,我不想去改变 less 内部的逻辑函数采用 MyClass 而不是 double 作为第二个参数。
class MyClass
{
public :
MyClass(): _dValue1(0.0),_dValue2(0.0),_dValue3(0.0)
{
}
MyClass(double dValue1, double dValue3, double dValue2): _dValue2(dValue2),_dValue3(dValue3),_dValue1(dValue1)
{
}
~MyClass() {}
double getValue1() {return _dValue1;}
double getValue3() {return _dValue3;}
double getValue2() {return _dValue2;}
double _dValue1;
double _dValue3;
double _dValue2;
public:
friend class vector<MyClass>;
int compare(const MyClass & t1, const MyClass & t2)
{
if (t1._dValue1 < t2._dValue1)
return -1;
else if (t2._dValue1 < t1._dValue1)
return 1;
else
return 0;
}
bool operator> (const MyClass & rhs)
{
if ( _dValue1 > rhs._dValue1)
return true;
else
return false;
}
bool operator< (const MyClass & rhs)
{
if ( _dValue1 < rhs._dValue1)
return true;
else
return false;
}
};
编辑:
MSalters的回答表明谓词的调试和发布实现并不相同,这使得它在发布中编译,而不是在我的情况下调试(因为代码不是很整洁,不应该使用比较函数有 2 种不同类型)。为了能够在调试中使用此代码,我所做的黑客操作也是将此行放在任何包含之前(请注意,首选解决方案应该是拥有更好的比较功能,但在我的情况下这是不可能的):
#define _HAS_ITERATOR_DEBUGGING 0
I'm trying to compile a small COM dll (using visual studio 2008 pro), and it compiles fine in release, but when I try to compile it in debug I get a compilation error:
error C2664: 'bool (MyClass &, double)': cannot convert parameter 2
from 'MyClass' to 'double'.
Now this error comes from a line in the code where I do this (note that someValueThatIsADouble is of type double):
std::vector<MyClass>::iterator iter = std::lower_bound(MyVector.begin(), MyVector.end(), someValueThatIsADouble, less);
And the less function is defined this way:
bool less(MyClass& a, double b);
I don't understand why I get this error, and if there is a good reason for this error, why do I only get it in Debug (and not in Release)? The dll, when compiled in Release, runs fine and doesn't crash. Also, I checked and there is no #ifdef DEBUG
or things like that which could change the code that is compiled in debug and in release.
EDIT:
I didn't write the code myself and it is an algorithm I don't know much about so I don't know what the double value is supposed to represent and I don't want to go change the logic inside the less function to take a MyClass instead of a double as a second parameter.
class MyClass
{
public :
MyClass(): _dValue1(0.0),_dValue2(0.0),_dValue3(0.0)
{
}
MyClass(double dValue1, double dValue3, double dValue2): _dValue2(dValue2),_dValue3(dValue3),_dValue1(dValue1)
{
}
~MyClass() {}
double getValue1() {return _dValue1;}
double getValue3() {return _dValue3;}
double getValue2() {return _dValue2;}
double _dValue1;
double _dValue3;
double _dValue2;
public:
friend class vector<MyClass>;
int compare(const MyClass & t1, const MyClass & t2)
{
if (t1._dValue1 < t2._dValue1)
return -1;
else if (t2._dValue1 < t1._dValue1)
return 1;
else
return 0;
}
bool operator> (const MyClass & rhs)
{
if ( _dValue1 > rhs._dValue1)
return true;
else
return false;
}
bool operator< (const MyClass & rhs)
{
if ( _dValue1 < rhs._dValue1)
return true;
else
return false;
}
};
Edit:
MSalters' answer showed that the debug and release implementations of the predicates weren't the same, which made it compile in release and not in debug in my case (because the code isn't very neat and should not use a comparison function with 2 different types). The hack I did to be able to use this code in debug also was to put this line before any includes (note that the preferred solution should be to have a better comparison function, but in my case it wasn't possible):
#define _HAS_ITERATOR_DEBUGGING 0
发布评论
评论(3)
该错误消息表明您正在使用 MSVC。它的库实现包含对谓词的调试检查。特别是,对于偏序谓词(例如您的
less
),我认为它测试是否Pred(a,b) && Pred(b,a) == false
。显然这在这里行不通。(谓词的常见错误之一是人们习惯于定义一个顺序,使得
a 和
b 都满足。有许多
时捕获错误。代码 > 运行时的值;无法在编译时捕获理论错误) ;
在这种情况下会崩溃,这就是为什么现在有一些调试检查来防止此类错误,但它们仍然只会在您实际上设法传递一对错误的a,b
a,bThe error message suggests you're using MSVC. It's library implementation contains debug checks on predicates. In particular, for a partial order predicate (such as your
less
), I think it tests whetherPred(a,b) && Pred(b,a) == false
. Obviously that won't work here.(One of the common errors with predicates is that people used to define an order such that both
a<b
andb<a
. There are many<algorithm>
s that break down in that case, which is why there are now some debug checks to prevent such errors. Still they only catch errors if you actually manage to pass a pair of bada,b
values at runtime; they can't catch theoretical errors at compile time)尝试使用:
Try with :
first :向前迭代器,寻址要搜索的范围中第一个元素的位置。
last :向前迭代器,寻址要搜索的范围中最后一个元素之后的位置。
val :在有序范围内搜索其第一个位置或可能的第一个位置的值。
comp :用户定义的谓词函数对象,定义一个元素小于另一个元素的含义。二元谓词采用两个参数,满足时返回 true,不满足时返回 false。
它在发行版中编译,因为在 std 的发行版实现中禁用了一些检查。但它不应该编译: val 应该是 MyClass 类型而不是 double 类型,然后 less 即使在发布中也不会再编译。
first : A forward iterator addressing the position of the first element in the range to be searched.
last : A forward iterator addressing the position one past the final element in the range to be searched.
val : The value whose first position or possible first position is being searched for in the ordered range.
comp : User-defined predicate function object that defines sense in which one element is less than another. A binary predicate takes two arguments and returns true when satisfied and false when not satisfied.
It compiles in release because some checks are deactivated in release implementation of std. But it should not compile : val should be of type MyClass and not of type double and then less won't compile anymore even in release.