简体   繁体   中英

c++ compile error in debug but not in release

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 

The 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 whether Pred(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 and b<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 bad a,b values at runtime; they can't catch theoretical errors at compile time)

Try with:

bool less(const MyClass& a, const MyClass& b);
template<class ForwardIterator, class Type, class BinaryPredicate>
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const Type& val, BinaryPredicate comp);

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM