Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Sorting a vector of a user defined type

Sorting a vector of a user defined type

Scheduled Pinned Locked Moved C / C++ / MFC
algorithmshelpcsharpcssvisual-studio
15 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Lost User

    I just checked some similar sort code that I use and the only difference is that my sort function takes two const reference params. Try changing your sort function:

    bool less_than(const item_calculation**&** a, const item_calculation& b )
    {
    return a.prediction < b.prediction;
    };

    A Offline
    A Offline
    avimitrani
    wrote on last edited by
    #6

    I have already changed the definition adding the consts and references. this doesn't make a difference. Avi.

    L 1 Reply Last reply
    0
    • A avimitrani

      I have already changed the definition adding the consts and references. this doesn't make a difference. Avi.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #7

      Avi, Weird, as I just created a test console app (using VS2005) and it builds without errors:

      #include "stdafx.h"
      #include <vector>
      #include <algorithm>

      struct item_calculation
      {
      int item_num;
      float weight;
      float contribution;
      float prediction;
      };

      bool less_than(const item_calculation& a, const item_calculation& b)
      {
      return a.prediction < b.prediction;
      };

      int _tmain(int argc, _TCHAR* argv[])
      {
      std::vector<item_calculation> items;
      // Add items to the vector here...
      std::sort(items.begin(), items.end(), less_than);
      }

      A 1 Reply Last reply
      0
      • A avimitrani

        what is the meaning of the added lines: item_calculation() : item_num(0), weight(0.0), contribution(0.0), prediction(0.0) {} Thanks, Avi.

        Z Offline
        Z Offline
        Zac Howland
        wrote on last edited by
        #8

        In C++, class and struct are pretty much the same keyword (class defaults to private protection, while struct defaults to public -- that is pretty much the only major difference). Thus, you can create constructors for structs just as you would a class. The code below creates a default constructor and initializes each variable to a value (in this case, all 0's).

        avimitrani wrote:

        item_calculation() : item_num(0), weight(0.0), contribution(0.0), prediction(0.0) {}

        It is almost the same as writing it this way:

        item_calculation()
        {
        	item_num = 0;
        	weight = 0.0;
        	contribution = 0.0;
        	prediction = 0.0;
        }
        

        except that the first case is more efficient because the members are created and initialzed at the same time.

        If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

        A 1 Reply Last reply
        0
        • C Chris Losinger

          it initializes those variables

          image processing | blogging

          A Offline
          A Offline
          avimitrani
          wrote on last edited by
          #9

          Why should they be initialized? (this is the only difference between your code and mine)

          1 Reply Last reply
          0
          • Z Zac Howland

            In C++, class and struct are pretty much the same keyword (class defaults to private protection, while struct defaults to public -- that is pretty much the only major difference). Thus, you can create constructors for structs just as you would a class. The code below creates a default constructor and initializes each variable to a value (in this case, all 0's).

            avimitrani wrote:

            item_calculation() : item_num(0), weight(0.0), contribution(0.0), prediction(0.0) {}

            It is almost the same as writing it this way:

            item_calculation()
            {
            	item_num = 0;
            	weight = 0.0;
            	contribution = 0.0;
            	prediction = 0.0;
            }
            

            except that the first case is more efficient because the members are created and initialzed at the same time.

            If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

            A Offline
            A Offline
            avimitrani
            wrote on last edited by
            #10

            Yes, but why should initialization make a difference? Before I use sort() I loop over the vector, and fill thr struct fields.

            Z 1 Reply Last reply
            0
            • L Lost User

              Avi, Weird, as I just created a test console app (using VS2005) and it builds without errors:

              #include "stdafx.h"
              #include <vector>
              #include <algorithm>

              struct item_calculation
              {
              int item_num;
              float weight;
              float contribution;
              float prediction;
              };

              bool less_than(const item_calculation& a, const item_calculation& b)
              {
              return a.prediction < b.prediction;
              };

              int _tmain(int argc, _TCHAR* argv[])
              {
              std::vector<item_calculation> items;
              // Add items to the vector here...
              std::sort(items.begin(), items.end(), less_than);
              }

              A Offline
              A Offline
              avimitrani
              wrote on last edited by
              #11

              Thanks for the effort, Robert. This problem buggs me exactly because the code seems to me to be correct. In my case all the declarations (struct, function) are made inside a class definition, and sort() is called from inside a member fonction. can this make any difference?

              Z 1 Reply Last reply
              0
              • A avimitrani

                Yes, but why should initialization make a difference? Before I use sort() I loop over the vector, and fill thr struct fields.

                Z Offline
                Z Offline
                Zac Howland
                wrote on last edited by
                #12

                Initialization is important, but that won't fix your problem. The important differences between your code and mine are bolded:

                // struct definition
                struct item_calculation
                {
                	int item_num;
                	float weight;
                	float contribution;
                	float prediction;
                
                	item_calculation() : item_num(0), weight(0.0), contribution(0.0), prediction(0.0)
                	{}
                };
                
                // this is actually a better way of doing it
                bool operator< (const item_calculatioin& lhs, const item_calculation& rhs)
                {
                	return lhs.prediction < rhs.prediction;
                }
                
                // sort call
                sort(found_items.begin(), found_items.end());	// less is the default predicate
                

                Having the operator outside the class definition is a better way (and least likely to run into problems when using algorithms) to define it. For classes, you may want to declare them as friend functions as needed. There is no need to define a new less_than method. By default, sort calls the less<T> functor which calls the overriden operator< for and object of type T (in this case, item_calculation). Looking back at your original post, it looks like you were trying to declare item_calculation as a private inner class to your App class. Am I correct?

                If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                1 Reply Last reply
                0
                • A avimitrani

                  Thanks for the effort, Robert. This problem buggs me exactly because the code seems to me to be correct. In my case all the declarations (struct, function) are made inside a class definition, and sort() is called from inside a member fonction. can this make any difference?

                  Z Offline
                  Z Offline
                  Zac Howland
                  wrote on last edited by
                  #13

                  avimitrani wrote:

                  In my case all the declarations (struct, function) are made inside a class definition, and sort() is called from inside a member fonction. can this make any difference?

                  Yes. Move the overriden operator< outside of your app class and declare it as a friend to your app class.

                  #include <iostream>
                  #include <vector>
                  #include <algorithm>
                  #include <iterator>
                  
                  using namespace std;
                  
                  class MyClass
                  {
                  public:
                          MyClass() { initMe(); }
                  
                          void sortMe() { sort(found_items.begin(), found_items.end()); }
                          void showMe() { copy(found_items.begin(), found_items.end(), ostream_iterator<item_calculation>(cout, " ")); }
                  private:
                          struct item_calculation
                          {
                                  int item_num;
                                  float weight;
                                  float contribution;
                                  float prediction;
                  
                                  item_calculation() : item_num(0), weight(0.0), contribution(0.0), prediction(0.0)
                                  {}
                  
                                  item_calculation(int in, float w, float c, float p) : item_num(in), weight(w), contribution(c), prediction(p)
                                  {}
                  
                          };
                  
                          vector<item_calculation> found_items;
                  
                          void initMe()
                          {
                                  for (int i = 10; i > 0; --i)
                                  {
                                          float f = static_cast<float>(i);
                                          item_calculation ic(i, f, f, f);
                                          found_items.push_back(ic);
                                  }
                          }
                  
                          friend bool operator< (const item_calculation& lhs, const item_calculation& rhs);
                          friend ostream& operator<<(ostream& os, const item_calculation& ic);
                  };
                  bool operator< (const MyClass::item_calculation& lhs, const MyClass::item_calculation& rhs)
                  {
                          return lhs.prediction < rhs.prediction;
                  }
                  
                  ostream& operator<<(ostream& os, const MyClass::item_calculation& ic)
                  {
                          os << ic.item_num;
                          return os;
                  }
                  
                  int main()
                  {
                          MyClass me;
                          me.showMe();
                          cout << endl;
                          me.sortMe();
                          me.showMe();
                  }
                  

                  If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                  A 1 Reply Last reply
                  0
                  • Z Zac Howland

                    avimitrani wrote:

                    In my case all the declarations (struct, function) are made inside a class definition, and sort() is called from inside a member fonction. can this make any difference?

                    Yes. Move the overriden operator< outside of your app class and declare it as a friend to your app class.

                    #include <iostream>
                    #include <vector>
                    #include <algorithm>
                    #include <iterator>
                    
                    using namespace std;
                    
                    class MyClass
                    {
                    public:
                            MyClass() { initMe(); }
                    
                            void sortMe() { sort(found_items.begin(), found_items.end()); }
                            void showMe() { copy(found_items.begin(), found_items.end(), ostream_iterator<item_calculation>(cout, " ")); }
                    private:
                            struct item_calculation
                            {
                                    int item_num;
                                    float weight;
                                    float contribution;
                                    float prediction;
                    
                                    item_calculation() : item_num(0), weight(0.0), contribution(0.0), prediction(0.0)
                                    {}
                    
                                    item_calculation(int in, float w, float c, float p) : item_num(in), weight(w), contribution(c), prediction(p)
                                    {}
                    
                            };
                    
                            vector<item_calculation> found_items;
                    
                            void initMe()
                            {
                                    for (int i = 10; i > 0; --i)
                                    {
                                            float f = static_cast<float>(i);
                                            item_calculation ic(i, f, f, f);
                                            found_items.push_back(ic);
                                    }
                            }
                    
                            friend bool operator< (const item_calculation& lhs, const item_calculation& rhs);
                            friend ostream& operator<<(ostream& os, const item_calculation& ic);
                    };
                    bool operator< (const MyClass::item_calculation& lhs, const MyClass::item_calculation& rhs)
                    {
                            return lhs.prediction < rhs.prediction;
                    }
                    
                    ostream& operator<<(ostream& os, const MyClass::item_calculation& ic)
                    {
                            os << ic.item_num;
                            return os;
                    }
                    
                    int main()
                    {
                            MyClass me;
                            me.showMe();
                            cout << endl;
                            me.sortMe();
                            me.showMe();
                    }
                    

                    If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                    A Offline
                    A Offline
                    avimitrani
                    wrote on last edited by
                    #14

                    Thanks again, Zac Your suggestion strikes me as the most correct way to do it. I managed to compile the project by using a different solution: struct item_calculation // To be used inside 'recommend' { int item_num; float weight; float contribution; float prediction; bool operator<(const item_calculation &b) { return prediction < b.prediction; }; }; This should work too, but I'll opt for the friend function option. Many thanks, Avi.

                    Z 1 Reply Last reply
                    0
                    • A avimitrani

                      Thanks again, Zac Your suggestion strikes me as the most correct way to do it. I managed to compile the project by using a different solution: struct item_calculation // To be used inside 'recommend' { int item_num; float weight; float contribution; float prediction; bool operator<(const item_calculation &b) { return prediction < b.prediction; }; }; This should work too, but I'll opt for the friend function option. Many thanks, Avi.

                      Z Offline
                      Z Offline
                      Zac Howland
                      wrote on last edited by
                      #15

                      The only problem you will run into is if the item_calculation struct is a private inner class, the opeartor< will be "private", so it won't be able to be used outside the outer class (that is, sort may have issues with it). That goes away if it is a public inner class, or if you override the operators outside the class. There are other reasons to override binary operators outside the class they operate on, but that goes beyond the scope of this question.

                      If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups