0

I have two vector. The first one is a vector of objects of some class. The second one is a vector which elements point to the objects of the first vector.

I have two question for you. The first one is: there is a better or more elegant way to declare and initialize the vector of pointers?

The second one is a bit more complex to explain. Suppose that i want to see the elements of the first vector in a descending order. All i have to do is to overload the operator < and sort them. Well, suppose now that i want to see the elements of the first vector in a descending order without change the order of its element but only with the help of the second vector. In other words, I want to sort the element of the second vector looking at what they point to and not, as usual, looking at its elements since they are addresses. What should I do? Overload the operator < with other type of arguments? Pass another order function to sort?

I give you a Minimal, Complete, and Verifiable example to compile with g++ -std=c++11 -o example example.cpp.

example.ccp

#include <iostream>
#include <algorithm>
#include <vector>

class MyClass{
    public:
        int a;
        int b;
        MyClass(int a, int b) : a(a), b(b){};
        bool operator<(const MyClass &obj)const{return (this->a + this->b) < (obj.a + obj.b);};
};

int main(int argc, char* argv[]){
    std::vector<MyClass> vector1;
    vector1.push_back({4, 5});
    vector1.push_back({5, 6});
    vector1.push_back({6, 7});
    vector1.push_back({1, 2});
    vector1.push_back({2, 3});
    vector1.push_back({3, 4});

    std::vector<MyClass*> vector2;
    std::vector<MyClass>::iterator i;
    for(i = vector1.begin(); i != vector1.end(); i++)
        vector2.push_back(&(*i));

    std::cout << "element pointed to by vector2 unsorted: " << std::endl;
    for(int j = 0; j < vector2.size(); j++)
        std::cout << vector2[j]->a << " " << vector2[j]->b << std::endl;        

    /* Insert here how I should sort vector2 */
    // std::sort (vector2.begin(), vector2.end());  <-- Obviously this doesn't work

    std::cout << "element pointed to by vector2 sorted: " << std::endl;
    for(int j = 0; j < vector2.size(); j++)
        std::cout << vector2[j]->a << " " << vector2[j]->b << std::endl;    


    return 0;
}
5
  • 2
    I do not think you want to do this. anything that causes a reallocation of vector1 is going to break vector2 Commented Oct 22, 2015 at 14:36
  • The second vector could be a vector of indexes instead of pointers. Commented Oct 22, 2015 at 14:40
  • I need to do it because in my project i have a very large number of elements in vector1 and they are also relatively big type. I think that if vector1 is filled with const value the problem that you say is solved. Commented Oct 22, 2015 at 14:41
  • @JoachimPileborg: explain in a better way what you mean by that. Commented Oct 22, 2015 at 14:41
  • 1
    Like @NathanOliver said, if the first vector needs to reallocate its data (which can happen if you add elements) then the pointers will become invalid, as will all iterators. But the indexes of the first vector will only become invalid if you remove an element from the vector. Commented Oct 22, 2015 at 14:45

1 Answer 1

1

It sounds to me like the first vector is a red herring and this would do:

bool compare(const MyClass* lhs, const MyClass* rhs)
{
    return *lhs < *rhs;
}

std::sort (vector2.begin(), vector2.end(), compare);

A more stable variant in the presence of modifications to vector1 is to store indexes instead of pointers:

std::vector<size_t> vector2(vector1.size());
std::iota(vector2.begin(), vector2.end(), 0);

std::sort (vector2.begin(), 
           vector2.end(), 
           [&](int l, int r) { return vector1[l] < vector1[r]; });

std::cout << "element pointed to by vector2 sorted: " << std::endl;
for(int j = 0; j < vector2.size(); j++)
    std::cout << vector1[vector2[j]].a << " " << vector1[vector2[j]].b << std::endl;
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, this would work if you substitute int* with MyClass*.
It's possible to implement the function in the first solution inside the class MyClass?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.