CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Mar 2008
    Posts
    38

    functor or extractor for a vector question

    I'm new to functors (still trying to grasp the concept) and I wanted to know if I can do the same as the following code with a functor? It basically converts a vector of a two item struct into two vectors.

    Code:
    typedef struct
    {
    short A;
    short B;
    } MyData;
    
    ..........
    
    std::vector<MyData> history;
    ........
    
    const unsigned int listSize = history.size();
    std::vector<short> myA, myB;
     
    for (int i = 0; i < listSize; i++)
    {
    	//extract A data from history
    	myA.push_back(history[i].A);
    	//extract p-p interval data from history
    	myB.push_back(history[i].B);
    }

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: functor or extractor for a vector question

    Yeah, you could. If it were me I'd do:
    1) Write a functor which takes pointers or references to myA and myB on construction, and takes a vector<MyData>::value_type as the argument to its operator().
    2) The operator() does the two push_backs.
    3) Use the functor with std::for_each.

  3. #3
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: functor or extractor for a vector question

    Yes, you can. Create a functor that takes references to your two vectors as arguments to its constructor. The operator() should take one argument of type MyData.
    Code:
    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    struct MyData
    {
      short A;
      short B;
      MyData(short a, short b) : A(a), B(b) {}
    };
    
    struct Functor {
      std::vector<short> &ra, &rb;
      Functor(std::vector<short>& a , std::vector<short>& b) : ra(a), rb(b) {}
      void operator()(MyData arg1) {
        ra.push_back(arg1.A);
        rb.push_back(arg1.B);
      }
    };
    
    int main() {
      std::vector<MyData> history;
      history.push_back(MyData(1,1));
      history.push_back(MyData(2,4));
      history.push_back(MyData(3,9));
    
      std::vector<short> myA, myB;
    
      // Create a functor with references to myA and myB
      Functor f(myA, myB);
      std::for_each(history.begin(), history.end(), f);
    
      std::cout << "Content of vector myA\n";
      for (std::vector<short>::const_iterator it = myA.begin(); it != myA.end(); ++it)
        std::cout << *it << "\n";
      std::cout << "Content of vector myB\n";
      for (std::vector<short>::const_iterator it = myB.begin(); it != myB.end(); ++it)
        std::cout << *it << "\n";
    }
    Edit: Just saw that Lindley already replied while I was trying out an example
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  4. #4
    Join Date
    Mar 2008
    Posts
    38

    Re: functor or extractor for a vector question

    Quote Originally Posted by Lindley View Post
    Yeah, you could. If it were me I'd do:
    1) Write a functor which takes pointers or references to myA and myB on construction, and takes a vector<MyData>::value_type as the argument to its operator().
    2) The operator() does the two push_backs.
    3) Use the functor with std::for_each.
    thanks I think that is what I was looking for. The key being using pointers and value_type which I had never used. Let me see if I can code this now.

  5. #5
    Join Date
    Mar 2008
    Posts
    38

    Re: functor or extractor for a vector question

    Quote Originally Posted by treuss View Post
    Yes, you can. Create a functor that takes references to your two vectors as arguments to its constructor. The operator() should take one argument of type MyData.
    Code:
    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    struct MyData
    {
      short A;
      short B;
      MyData(short a, short b) : A(a), B(b) {}
    };
    
    struct Functor {
      std::vector<short> &ra, &rb;
      Functor(std::vector<short>& a , std::vector<short>& b) : ra(a), rb(b) {}
      void operator()(MyData arg1) {
        ra.push_back(arg1.A);
        rb.push_back(arg1.B);
      }
    };
    
    int main() {
      std::vector<MyData> history;
      history.push_back(MyData(1,1));
      history.push_back(MyData(2,4));
      history.push_back(MyData(3,9));
    
      std::vector<short> myA, myB;
    
      // Create a functor with references to myA and myB
      Functor f(myA, myB);
      std::for_each(history.begin(), history.end(), f);
    
      std::cout << "Content of vector myA\n";
      for (std::vector<short>::const_iterator it = myA.begin(); it != myA.end(); ++it)
        std::cout << *it << "\n";
      std::cout << "Content of vector myB\n";
      for (std::vector<short>::const_iterator it = myB.begin(); it != myB.end(); ++it)
        std::cout << *it << "\n";
    }
    Edit: Just saw that Lindley already replied while I was trying out an example
    Thanks. I got stuck and came back to see your post. Unfortunately I had done things in reverse. For some reason this stuff is counter intuitive for me right now.

    If speed is a concern, which it is for me, would this functor method be slower than my primitive loop method?

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: functor or extractor for a vector question

    In an optimized build there isn't likely to be a notable difference.

    However, what *could* speed you up is calling .reserve() on myA and myB with the size of the history vector beforehand.

    value_type which I had never used
    For vectors it probably doesn't matter---it's just going to be another name for MyData. However, it's useful for sets and maps since the type to use there isn't always obvious.

  7. #7
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: functor or extractor for a vector question

    Quote Originally Posted by sdcode View Post
    Thanks. I got stuck and came back to see your post. Unfortunately I had done things in reverse. For some reason this stuff is counter intuitive for me right now.
    Which part is counter-intuitive? The functor itself or the way it is used?

    Maybe it helps that the following code
    Code:
      Functor f(myA, myB);
      std::for_each(history.begin(), history.end(), f);
    is basically equivalent to
    Code:
      Functor f(myA, myB);
      for (std::vector<MyData>::iterator it = history.begin(); it != history.end(); ++it)
          f.operator()(*it);   // or in short f(*it);
    or, using indexes instead of iterators
    Code:
      Functor f(myA, myB);
      for (unsigned int i = 0; i < history.size(); ++i)
          f.operator()(history[i]);   // or in short f(history[i]);
    Now consider operator() to be a normal member function of Functor and I hope you will understand.
    Last edited by treuss; July 7th, 2009 at 02:34 PM.
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured