Invalid comparator for STL map
-
Hi I am getting invalid comparator for the following code and I just dont get it at the very end there is always a path to return
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange x) const {
if (esdid <= x.esdid) return esdid <= x.esdid;
if (start <= x.start) return start <= x.start; if (end <= x.end) return end <= x.end;
else
return FALSE; -
Hi I am getting invalid comparator for the following code and I just dont get it at the very end there is always a path to return
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange x) const {
if (esdid <= x.esdid) return esdid <= x.esdid;
if (start <= x.start) return start <= x.start; if (end <= x.end) return end <= x.end;
else
return FALSE;Shouldn't you be passing usingrange as a reference to your comparison function?
bool operator<(const usingrange**&** x) const
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.
-
Shouldn't you be passing usingrange as a reference to your comparison function?
bool operator<(const usingrange**&** x) const
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.
-
Shouldn't you be passing usingrange as a reference to your comparison function?
bool operator<(const usingrange**&** x) const
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.
this is were I am getting the exception at the line with STL_VERIFY
// FUNCTION TEMPLATE _Debug_lt_pred
template , _Remove_cvref_t<_Ty2>>, int> = 0>
constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept(
noexcept(_Pred(_Left, _Right)) && noexcept(_Pred(_Right, _Left))) {
// test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type
const auto _Result = static_cast(_Pred(_Left, _Right));
if (_Result) {
_STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator");this is my code
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange& x) const {
if (esdid < x.esdid)
return esdid < x.esdid;
if (start < x.start)
return start < x.start;
if (end < x.end) return end < x.end;
else
return x.end < end;when I change mt code to
bool operator<(const usingrange& x) const {
return start < x.start;
}
everything works I dont get it the operator is excepting a bool retrun code true or false in either I retrun that
-
this is were I am getting the exception at the line with STL_VERIFY
// FUNCTION TEMPLATE _Debug_lt_pred
template , _Remove_cvref_t<_Ty2>>, int> = 0>
constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept(
noexcept(_Pred(_Left, _Right)) && noexcept(_Pred(_Right, _Left))) {
// test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type
const auto _Result = static_cast(_Pred(_Left, _Right));
if (_Result) {
_STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator");this is my code
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange& x) const {
if (esdid < x.esdid)
return esdid < x.esdid;
if (start < x.start)
return start < x.start;
if (end < x.end) return end < x.end;
else
return x.end < end;when I change mt code to
bool operator<(const usingrange& x) const {
return start < x.start;
}
everything works I dont get it the operator is excepting a bool retrun code true or false in either I retrun that
Does your ESDID class have an
operator<()
function? If not, add one. -
Does your ESDID class have an
operator<()
function? If not, add one. -
Does your ESDID class have an
operator<()
function? If not, add one.still getting the exception if the key to the map is a structure consisting of a char[4] and 2 int how would I set < operator the only way I got it to work was by return int1 < x.int1 what would like to do is concatenate all of them in 12 bytes and compare 12 bytes against 12 bytes thanks
-
still getting the exception if the key to the map is a structure consisting of a char[4] and 2 int how would I set < operator the only way I got it to work was by return int1 < x.int1 what would like to do is concatenate all of them in 12 bytes and compare 12 bytes against 12 bytes thanks
Since my the total of my data was 12 bytes I was lucky there happened to be a data type 16 bytes long double just filled first 4 bytes with zeros and here is the code
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange& x) const {
union
{
long double a;
char str1[16];
}c;
union
{
long double b;
char str2[16];
}d;::memset(&c.str1, 0x00, 16); ::memset(&d.str2, 0x00, 16); ::memcpy(&c.str1\[4\], &esdid, 4); ::memcpy(&c.str1\[8\],&start,4); ::memcpy(&c.str1\[12\], &end, 4); ::memcpy(&d.str2\[4\], &x.esdid, 4); ::memcpy(&d.str2\[8\], &x.start, 4); ::memcpy(&d.str2\[12\], &x.end, 4); return c.a < d.b; // return usingrange < x; // if (start < x.start) // return start < x.start;
// return x.end < end;
}
};
-
still getting the exception if the key to the map is a structure consisting of a char[4] and 2 int how would I set < operator the only way I got it to work was by return int1 < x.int1 what would like to do is concatenate all of them in 12 bytes and compare 12 bytes against 12 bytes thanks
Since my data was 12 bytes long I was lucky there happened to be a data type 16 bytes long a "long double" I just filled the first 4 bytes with zeros and
;
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange& x) const {
union
{
long double a;
char str1[16];
}c;
union
{
long double b;
char str2[16];
}d;::memset(&c.str1, 0x00, 16); ::memset(&d.str2, 0x00, 16); ::memcpy(&c.str1\[4\], &esdid, 4); ::memcpy(&c.str1\[8\],&start,4); ::memcpy(&c.str1\[12\], &end, 4); ::memcpy(&d.str2\[4\], &x.esdid, 4); ::memcpy(&d.str2\[8\], &x.start, 4); ::memcpy(&d.str2\[12\], &x.end, 4); return c.a < d.b; // return usingrange < x; // if (start < x.start) // return start < x.start;
// return x.end < end;
}
};
-
Since my data was 12 bytes long I was lucky there happened to be a data type 16 bytes long a "long double" I just filled the first 4 bytes with zeros and
;
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange& x) const {
union
{
long double a;
char str1[16];
}c;
union
{
long double b;
char str2[16];
}d;::memset(&c.str1, 0x00, 16); ::memset(&d.str2, 0x00, 16); ::memcpy(&c.str1\[4\], &esdid, 4); ::memcpy(&c.str1\[8\],&start,4); ::memcpy(&c.str1\[12\], &end, 4); ::memcpy(&d.str2\[4\], &x.esdid, 4); ::memcpy(&d.str2\[8\], &x.start, 4); ::memcpy(&d.str2\[12\], &x.end, 4); return c.a < d.b; // return usingrange < x; // if (start < x.start) // return start < x.start;
// return x.end < end;
}
};
That has a couple of issues. Firstly, you are invoking undefined behavior: [Union declaration - cppreference.com](https://en.cppreference.com/w/cpp/language/union#:~:text=It is undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement%2C as a non-standard language extension%2C the ability to read inactive members of a union.) Secondly, you're expecting that the bit patterns of 2 doubles can be compared. This may not be the case, as you may a NaN this way, and then any comparison will return false:
[k5054@localhost tmp]$ cat example.c
#includeint main()
{
double d = 0.0 / 0.0; // produces NaN
printf("1.0 < d = %d\n", 1.0 < d);
printf("d < 1.0 = %d\n", d < 1.0);
printf("d == d = %d\n", d == d);
}
[k5054@localhost tmp]$ gcc example.c -o example
[k5054@localhost tmp]$ ./example
1.0 < d = 0
d < 1.0 = 0
d == d = 0
[k5054@localhost tmp]$As we can see in the above code, NaN compared to anything, even itself returns false. If all you want to do is compare bits, you might as well just go ahead and use
memcmp()
*#35;include
struct usingrange {
ESDID esdid;
int start;
int end;
// ... other stuff ...
bool operator<(const usingrange& x)const {
return ::memcmp(this, &x, sizeof(*this)
}
};This relies on the fact that the sizeof a struct or a class is the size of its individual members. This only becomes tricky if your struct/class includes STL or other objects like std::string or std::vector.
Keep Calm and Carry On
-
That has a couple of issues. Firstly, you are invoking undefined behavior: [Union declaration - cppreference.com](https://en.cppreference.com/w/cpp/language/union#:~:text=It is undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement%2C as a non-standard language extension%2C the ability to read inactive members of a union.) Secondly, you're expecting that the bit patterns of 2 doubles can be compared. This may not be the case, as you may a NaN this way, and then any comparison will return false:
[k5054@localhost tmp]$ cat example.c
#includeint main()
{
double d = 0.0 / 0.0; // produces NaN
printf("1.0 < d = %d\n", 1.0 < d);
printf("d < 1.0 = %d\n", d < 1.0);
printf("d == d = %d\n", d == d);
}
[k5054@localhost tmp]$ gcc example.c -o example
[k5054@localhost tmp]$ ./example
1.0 < d = 0
d < 1.0 = 0
d == d = 0
[k5054@localhost tmp]$As we can see in the above code, NaN compared to anything, even itself returns false. If all you want to do is compare bits, you might as well just go ahead and use
memcmp()
*#35;include
struct usingrange {
ESDID esdid;
int start;
int end;
// ... other stuff ...
bool operator<(const usingrange& x)const {
return ::memcmp(this, &x, sizeof(*this)
}
};This relies on the fact that the sizeof a struct or a class is the size of its individual members. This only becomes tricky if your struct/class includes STL or other objects like std::string or std::vector.
Keep Calm and Carry On
The return using memcmp as operands will get an exception in order to get around this I need to to have to have the syntax return operand1 < operand2 truthfully the order of the items is not that important as long as I am able to retrieve the data by key thanks
-
Since my data was 12 bytes long I was lucky there happened to be a data type 16 bytes long a "long double" I just filled the first 4 bytes with zeros and
;
struct usingrange
{
ESDID esdid;
int start;
int end;usingrange() { start = 0; end = 0; return; }
bool operator<(const usingrange& x) const {
union
{
long double a;
char str1[16];
}c;
union
{
long double b;
char str2[16];
}d;::memset(&c.str1, 0x00, 16); ::memset(&d.str2, 0x00, 16); ::memcpy(&c.str1\[4\], &esdid, 4); ::memcpy(&c.str1\[8\],&start,4); ::memcpy(&c.str1\[12\], &end, 4); ::memcpy(&d.str2\[4\], &x.esdid, 4); ::memcpy(&d.str2\[8\], &x.start, 4); ::memcpy(&d.str2\[12\], &x.end, 4); return c.a < d.b; // return usingrange < x; // if (start < x.start) // return start < x.start;
// return x.end < end;
}
};
I think you're making it too complicated:
struct ESDID
{
char c[4];bool operator<(const ESDID& other) const
{
return c[0] < other.c[0] && c[1] < other.c[1] &&
c[2] < other.c[2] && c[3] < other.c[3];
}
}struct usingrange
{
ESDID esdid;
int start;
int end;bool operator<(const usingrange& other) const
{
return esdid < other.esdid && start < other.start &&
end < other.end;
}
}I've used && and < because you do not want
operator<()
to return true for two different objects when you swap them around. -
I think you're making it too complicated:
struct ESDID
{
char c[4];bool operator<(const ESDID& other) const
{
return c[0] < other.c[0] && c[1] < other.c[1] &&
c[2] < other.c[2] && c[3] < other.c[3];
}
}struct usingrange
{
ESDID esdid;
int start;
int end;bool operator<(const usingrange& other) const
{
return esdid < other.esdid && start < other.start &&
end < other.end;
}
}I've used && and < because you do not want
operator<()
to return true for two different objects when you swap them around.