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?
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.
STL Util a small headers-only library with various utility functions. Mainly for fun but feedback is welcome.
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:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 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.