I've read a couple of articles on these and can't understand why you would need them. Maybe I don't understand exactly what they are.
Could someone explain them to me in a "non-article" way?
This is a discussion on Functors within the C++ Programming forums, part of the General Programming Boards category; I've read a couple of articles on these and can't understand why you would need them. Maybe I don't understand ...
I've read a couple of articles on these and can't understand why you would need them. Maybe I don't understand exactly what they are.
Could someone explain them to me in a "non-article" way?
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
A class overloading the () operator to make it look like a function is called when in fact the operator is called.
MagosX.com
Give a man a fish and you feed him for a day.
Teach a man to fish and you feed him for a lifetime.
Yeah I know what it is I just don't see why you would want to do that.
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
lets say you want to pass the adress of a function in a class to another class...that will involve some really weird code and stuff. Instead you pass a functor. One thing i use them for when i need to.
a functor is just an object that behaves like a function. their useful when you need to store something that will later be applied to the data being passed to it.
Code:int filter(int num) { return num > 10 ? 10 : num < 5 ? 5 : num; } struct filter_object { filter_object(int least, int most) : minimum(least), maximum(most) { } int operator () (int num) const { return num > maximum ? maximum : num < minimum ? minimum : num; } int minimum, maximum; }; template <class Function> void apply_filter(int * ptr, const Function & fnc) { *ptr = fnc(*ptr); } int main(void) { int x = 21; apply_filter(&x, filter); apply_filter(&x, filter_object(8, 20)); return 0; }
Code:int main(void){srand(time(0));for(double l=rand(),l0=0,l00=0;;l0+=0.1){for(double l000=0;l000 <1;l000+=.001,l+=((double)rand()/RAND_MAX)/0x64,l00+=((sin(l*0x8*atan(l0)*l000-(l0*0x8*atan (l)))*0.5)+0.5)){l00-=floor(l00);for(size_t l0000=0,l00000=(size_t)(0x50*(l00));l0000<l00000;++l0000 )putchar(0x20);putchar(0x61+(int)((double)rand()/RAND_MAX*0x1a));putchar('\n');}}return 0;}
Ok thanks guys.![]()
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
You can think of a functor as a function that also has some variables to store data in. That way you can pass a function around with some data attached.
Next up: functionoids.
Ugh... I was going to ask about dators next, but go on.Originally Posted by 7stud
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
You can also use operator() to make your object emulate a multi dimensional array, kind of like operator[] only with multiple parameters.
Here's a small chunk of code I toyed about with a while ago, using functors to make life easier when using STL algorithms.
Sometimes using STL algorithms, you wish to pass an extra parameter to the predicate - usually this is accomplished using std::bind1st or std::bind2nd. This is OK - except that you can't pass more than one extra parameter. Some people also don't like the way bind1st/bind2nd reads... so you can do this instead.
Code:/* Functor to find a single character inside a string */ class isCharInString { char ch; public: isCharInString( char c ): ch( c ) { } // Additional args passed through constructor bool operator()( const std::string& str ) const { return str.find( ch ) != std::string::npos; } };
Example of using functor, with a vector of std::string:The above should output the lineCode:typedef std::vector<std::string>::iterator vIterator; int main() { std::vector<std::string> foo; foo.push_back("qwertyuiop"); foo.push_back("asdfghjkl"); foo.push_back("zxcvbnm"); vIterator iter = std::find_if(foo.begin(), foo.end(), isCharInString('c') ); if (iter != foo.end()) std::cout << *iter; }Code:zxcvbnm
Last edited by Bench82; 04-25-2006 at 09:51 AM.