Reputation: 1154
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;
}
Upvotes: 0
Views: 560
Reputation: 66451
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;
Upvotes: 1