|
-
July 7th, 2009, 12:55 PM
#1
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);
}
-
July 7th, 2009, 01:03 PM
#2
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.
-
July 7th, 2009, 01:18 PM
#3
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.
-
July 7th, 2009, 01:20 PM
#4
Re: functor or extractor for a vector question
 Originally Posted by Lindley
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.
-
July 7th, 2009, 02:10 PM
#5
Re: functor or extractor for a vector question
 Originally Posted by treuss
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?
-
July 7th, 2009, 02:12 PM
#6
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.
-
July 7th, 2009, 02:31 PM
#7
Re: functor or extractor for a vector question
 Originally Posted by sdcode
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|