I have a simple struct
struct test
{
std::vector<Data> data;
void sort()
{
std::sort(data.begin(), data.end());
}
}
Data is a struct as well and has only simple fields and implements a < operator like following:
EDIT: changes according to feedbacks are included
struct Data
{
// ADAPTION 1 - comparator works with reference now
bool operator<(const Data &data) const
// bool operator<(const Data data)
{
// 1) sortieren nach Typ
if (type < data.type)
return true;
else if (type > data.type)
return false;
// 2) nach name sortieren
if(strlen(strName) > 0)
{
if (strncmp(strName, data.strName, 50) < 0)
return true;
else if (strncmp(strName, data.strName, 50) > 0)
return false;
}
// ADAPTION 2 - added:
else if (data.strName[0]) // at least 1 character...
return true;
// 3) nach Spezialtyp sortieren
if(strlen(typeSpecial)>0)
{
if (strncmp(typeSpecial, data.typeSpecial, 50) < 0)
return true;
else if (strncmp(typeSpecial, data.typeSpecial, 50) > 0)
return false;
}
// ADAPTION 3 - added:
else if (data.strName[0]) // at least 1 character...
return true;
return false;
}
}
That's it. How can I get the vector iterators incompatible
error that way? I'm not copying any vector, I'm directly calling the sort function with the vector...
In Visual Studio 2005, I've never had a problem, in Visual Studio 2012 this problem appeared and I don't know why and how to avoid it
There're a few issues with your code:
bool operator<(const Data data)
...should be...
bool operator<(const Data& data) const
Then:
if(strlen(strName) > 0)
{
if (strncmp(strName, data.strName, 50) < 0)
return true;
else if (strncmp(strName, data.strName, 50) > 0)
return false;
}
...needs...
else if (data.strName[0]) // at least 1 character...
return true;
This is required to ensure strict weak ordering, which is a requirement of std::sort
's and means that when a < b
, !(b < a)
.
Similarly:
if(strlen(typeSpecial)>0)
{
if (strncmp(typeSpecial, data.typeSpecial, 50) < 0)
return true;
else if (strncmp(typeSpecial, data.typeSpecial, 50) > 0)
return false;
}
...needs...
else if (data.typeSpecial[0])
return true;
Your string comparisons would be much cleaner if you used std::string
s. If you do stick with ASCIIZ data, it would be better to use eg sizeof typeSpecial
instead of 50
etc.. You can improve performance and code concision by doing less comparisons and trusting strncmp
to handle empty strings appropriately (which it will):
if (type < data.Type) return true;
if (type > data.Type) return false;
int d = strncmp(strName, data.strName, sizeof strName);
if (d == 0)
d = strncmp(typeSpecial, data.typeSpecial, sizeof typeSpecial);
return d < 0;
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.