0
votes

I am new to C++ and am trying to sort a vector based on values in another vector. I am trying to implement this by creating a vector of structs and sorting the vector of stucts using the STL. The structs have 2 data items, one a CustomType and the other an int. I want this sorted in decreasing order of the int field, and have therefore included a boolean operator overloading to be able to use the STL sort (algorithm).

The struct is constructed in the function using references to the CustomType vector and an initially uninitialised int vector, and combining them into a vector of structs. The values for the ints are obtained by calling a separate member function of SomeClass (SomeFunc) on each item of the CustomType vector and another u_int8_t param (this function works fine by itself).

In the end, I want to replace the sorted CustomType objects based on the sorted struct sequence.

The implementation file (.cpp) has the following function:

void SomeClass::orderFunc(std::vector<CustomType>& x, std::vector<int>& y, u_int8_t param){
    std::vector<CustomStruct> xy_vec;
    y.assign(x.size(), 0);   
    int count  = int(x.size());
    
    for(int i=0; i != count; ++i){
        y[i] = SomeFunc(x[i], param);
    }

    for(int i = 0; i != count; ++i){
        xy_vec[i].var1 = x[i];
        xy_vec[i].var2 = y[i];
    }
    std::sort(xy_vec.begin(), xy_vec.end()); 
    for(int i = 0; i != count; ++i){
        x[i] = xy_vec[i].var2;
    }
}

The struct is defined in the SomeClass header file as below:

struct CustomStruct{
        CustomType var1;
        int var2;
        bool operator>(const CustomStruct& a) const{
            return (this->var2 > a.var2);
        }
    };

When this function is called, I get the following error:

invalid operands to binary expression

bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}

I can't understand why the bool operator overloading is invalid given that this is being defined for the int field of the struct.

What am I missing? Any help would be appreciated. Also, any suggestions for a more elegant way to do this would be great as well.

2

2 Answers

2
votes

You need to overload operator< and not operator>

bool operator<(const CustomStruct& a) const
{
    return (this->var2 < a.var2);
}

EDIT: For sorting in reverse order, you need to call std::sort with rbegin() and rend() (reverse) iterators:

std::sort(xy_vec.rbegin(), xy_vec.rend()); 

EDIT (again, as the question is too long, has 2 problems):

The vector xy_vec is empty, you need to call resize:

std::vector<CustomStruct> xy_vec;
// Resize here
xy_vec.resize(count);
for(int i = 0; i != count; ++i){
    xy_vec[i].var1 = x[i];
    xy_vec[i].var2 = y[i];

Or you can call push_back - I am not telling you all that. Please find!

2
votes

std::sort has two main overloads, one without a sort predicate that defaults to using operator < and one with a sort predicate (details here).

So you could write something like

struct CustomStructCmp {
    bool operator()(const CustomStruct& a, const CustomStruct& b) const
    {   
        return a.var2 > b.var2;
    }   
};

std::sort(xy_vec.begin(), xy_vec.end(), CustomStructCmp());

(if you are using C++11 then you could use a lambda instead).

Alternatively you could write

std::sort(xy_vec.begin(), xy_vec.end(), std::greater<CustomStruct>());

but I feel that it is more natural to directly use a functor/lambda rather than define operator> and use the std::greater functor.