简体   繁体   中英

C++ sorting array => vector iterators incompatible

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.

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