Thread: Functors

  1. #1
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709

    Functors

    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

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    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.

  3. #3
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    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

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    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.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    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;
    }

  6. #6
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    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

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    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.

  8. #8
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Quote Originally Posted by 7stud
    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.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    You can also use operator() to make your object emulate a multi dimensional array, kind of like operator[] only with multiple parameters.

  10. #10
    Registered User
    Join Date
    Feb 2006
    Posts
    312
    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:
    Code:
    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;
    }
    The above should output the line
    Code:
    zxcvbnm
    Last edited by Bench82; 04-25-2006 at 09:51 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Storing functors?
    By Elysia in forum C++ Programming
    Replies: 18
    Last Post: 11-13-2008, 03:21 AM
  2. Learning functors problem. Pointer to reference
    By stumcd in forum C++ Programming
    Replies: 5
    Last Post: 10-21-2008, 02:32 PM