STL Sorting: How to sort a 'std::vector' containing classes/structures?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3

Thread: STL Sorting: How to sort a 'std::vector' containing classes/structures?

  1. #1
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,060

    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.

  2. #2
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    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.

  3. #3
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    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
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center