I know similar issue has been answered at this link Help me fix this C++ std::set comparator but unfortunately I am facing exactly same issue and I am unable to understand the reason behind it thus need some help to resolve it.
I am using VS2010 and my release binary is running fine without any issue but the debug binary reports:
My comparator looks like this:
struct PathComp {
bool operator() (const wchar_t* path1, const wchar_t* path2) const
{
int c = wcscmp(path1, path2);
if (c < 0 || c > 0) {
return true;
}
return false;
}
};
My set is declared like this:
set<wchar_t*,PathComp> pathSet;
Could somebody suggest me why my debug binary is failing at this assertion? Is it because I am using wcscmp() function to compare the wide character string getting stored in my set?
Thanks in advance!!!
std::set
requires a valid comperator that behaves like operator<
or std::less
.
The std::set code detected that your operator< is not valid, and as a help to you triggered the assert you showed.
And indeed: your comperator looks like an operator!=
, not like an operator<
One of the rules an operator<
should follow, is that a<b
and b<a
cannot be both true. In your implementation, it is.
Correct your code to:
bool operator() (const wchar_t* path1, const wchar_t* path2) const
{
int c = wcscmp(path1, path2);
return (c < 0);
}
and you should be fine.
The problem is that your comparator does not induce a strict-weak ordering. It should only really return true for paths that are "less" - not for all that are different. Change it to:
struct PathComp {
bool operator() (const wchar_t* path1, const wchar_t* path2) const
{
int c = wcscmp(path1, path2);
if (c < 0) { // <- this is different
return true;
}
return false;
}
};
Alternatively, using only c > 0
will also work - but the set will have a reverse order.
The algorithm needs to know the difference between smaller and greater to work, just unequal does not give enough information. Without smaller-than/greater-than information, the set cannot possibly maintain an order - but that is what a set is all about.
After spending some more time on it we finally decided to take another approach which worked for me.
So we converted wchar_t* to string using this method:
// Converts LPWSTR to string
bool convertLPWSTRToString(string& str, const LPWSTR wStr)
{
bool b = false;
char* p = 0;
int bSize;
// get the required buffer size in bytes
bSize = WideCharToMultiByte(CP_UTF8,
0,
wStr,-1,
0,0,
NULL,NULL);
if (bSize > 0) {
p = new char[bSize];
int rc = WideCharToMultiByte(CP_UTF8,
0,
wStr,-1,
p,bSize,
NULL,NULL);
if (rc != 0) {
p[bSize-1] = '\0';
str = p;
b = true;
}
}
delete [] p;
return b;
}
And then stored that string in the in the set, by doing this I didn't had to worry about comparing the elements getting stored to make sure that all entries are unique.
// set that will hold unique path
set<string> strSet;
So all I had to do was this:
string str;
convertLPWSTRToString(str, FileName);
// store path in the set
strSet.insert(str);
Though I still don't know what was causing "Debug Assertion Failed" issue when I was using a set comparator (PathComp) for set<wchar_t*,PathComp> pathSet;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With