-
November 24th, 2005, 10:04 AM
#1
STL Sorting: How to sort a 'std::vector' containing classes/structures?
Q: How to sort a 'std::vector' containing classes/structures?
A:
- Sort by using a binary predicate and 'std::sort':
Code:
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
class MyData
{
public:
int m_iData;
string m_strSomeOtherData;
};
bool MyDataSortPredicate(const MyData& d1, const MyData& d2)
{
return d1.m_iData < d2.m_iData;
}
int main()
{
// Create a vector that contains elements of type MyData
vector<MyData> myvector;
// Add data to the vector
MyData data;
data.m_iData = 3;
myvector.push_back(data);
data.m_iData = 1;
myvector.push_back(data);
// Sort the vector using predicate and std::sort
std::sort(myvector.begin(), myvector.end(), MyDataSortPredicate);
// Dump the vector to check the result
for (vector<MyData>::const_iterator citer = myvector.begin();
citer != myvector.end(); ++citer)
{
cout << (*citer).m_iData << endl;
}
return 1;
}
Last edited by Marc G; June 6th, 2009 at 12:43 PM.
-
May 31st, 2009, 11:03 AM
#2
Re: STL Sorting: How to sort a 'std::vector' containing classes/structures?
Alternatively, you don't need to write a predicate function if there is a mechanism for comparing instances of class MyData. Notice how the class has an operator< defined. This is because the std::sort operation sorts with the std::less functor by default which requires that the objects within the container have the relational operator < defined for them.
Code:
class MyData
{
public:
int m_iData;
string m_strSomeOtherData;
bool operator<(MyData rhs) { return m_iData < rhs.m_iData; }
};
In addition, change the call to std::sort. Do not specify a predicate.
Code:
std::sort(myvector.begin(), myvector.end());
Last edited by Marc G; June 6th, 2009 at 12:41 PM.
-
May 31st, 2009, 11:39 AM
#3
Re: STL Sorting: How to sort a 'std::vector' containing classes/structures?
Here is another adaptation of the example that uses two different kinds of predicates. The predicate specified can be a function pointer or a functor which is a class that defines operator() so that the object when instantiated can be used just like a function would be. Notice that I had to add one more header inclusion to the functional header. This is because the functor inherits from binary_function which is defined within the std library.
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
class MyData
{
public:
static bool compareMyDataPredicate(MyData lhs, MyData rhs) { return (lhs.m_iData < rhs.m_iData); }
// declare the functor nested within MyData.
struct compareMyDataFunctor : public binary_function<MyData, MyData, bool>
{
bool operator()( MyData lhs, MyData rhs)
{
return (lhs.m_iData < rhs.m_iData);
}
};
int m_iData;
string m_strSomeOtherData;
};
int main()
{
// Create a vector that contents elements of type MyData
vector<MyData> myvector;
// Add data to the vector
MyData data;
for(unsigned int i = 0; i < 10; ++i)
{
data.m_iData = i;
myvector.push_back(data);
}
// shuffle the elements randomly
std::random_shuffle(myvector.begin(), myvector.end());
// Sort the vector using predicate and std::sort. In this case the predicate is a static
// member function.
std::sort(myvector.begin(), myvector.end(), MyData::compareMyDataPredicate);
// Dump the vector to check the result
for (vector<MyData>::const_iterator citer = myvector.begin();
citer != myvector.end(); ++citer)
{
cout << (*citer).m_iData << endl;
}
// Now shuffle and sort using a functor. It has the same effect but is just a different
// way of doing it which is more object oriented.
std::random_shuffle(myvector.begin(), myvector.end());
// Sort the vector using predicate and std::sort. In this case the predicate is a functor.
// the functor is a type of struct so you have to call its constructor as the third argument.
std::sort(myvector.begin(), myvector.end(), MyData::compareMyDataFunctor());
// Dump the vector to check the result
for (vector<MyData>::const_iterator citer = myvector.begin();
citer != myvector.end(); ++citer)
{
cout << (*citer).m_iData << endl;
}
return 1;
}
Last edited by Marc G; June 6th, 2009 at 12:40 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|