Thread: Map and Functor :: STL

  1. #1
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348

    Map and Functor :: STL

    Hi.

    How do you define a functor that handles elements in an STL map? For example:

    Code:
    std::map<int, char *> testMap;
    
    char *testChar = new char[10];
    _strcpy(testChar, "November");
    
    testMap.insert(std::pair<int, char *>(0, testChar));
    
    ...
    
    // Now I want to deallocate all values in testMap.
    
    std::for_each(testMap.begin(), testMap.end(), DeleteValue());
    How do you define DeleteValue functor that handles elements in an STL map?

    Thanks,
    Kuphryn

  2. #2
    Registered User
    Join Date
    Aug 2001
    Posts
    403
    use string

    if there is a reason you're not using string i'd like to hear it..

    if you have some legitimate need to use char:

    search your local STL reference for map::first and map::second, IIRC these are the names of the keys and values.

  3. #3
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    The question is about functors, not char *.

    std::map<int, std::string *> testMap;
    std::string *pText = new std::string;
    ...

    How do you define a functor that handles elements from a map?

    Kuphryn

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Well, without knowing much about the STL (and not caring either), it's hard to say exactly how it may be implemented. Basically, to build a functor, you need:

    - a structure to hold a pointer to an object, and a pointer to the function it will call.

    - a function to assign the above to a given structure.

    - for added genericity, derive the functor from a non-templated base-class.


    Code:
    class functor_container { public:
    virtual void invoke() = 0;
    };
    
    template <class type>
    class functor : public functor_container { public:
    functor(type* instance, void (type::* function)(void)){
     object = instance;
     invocation = function;
    }
    void invoke(){
     (*object.*invocation)();
    }
    private:
    type * object;
    void (type::*invocation)();
    };
    
    class test {
    public:
    String text;
    test(char * this_text)
     :text(this_text)
     { /* */ }
    void print( ){
     cout << text << endl;
     getch();
     }
    };
    
    
    int main(){
     
     test attempt("Hello from a functor...");
     
     functor <test> test_functor(&attempt, &test::print);
     
     system("pause");
    
     test_functor.invoke();
    
     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;
    }

  5. #5
    geek SilentStrike's Avatar
    Join Date
    Aug 2001
    Location
    NJ
    Posts
    1,141
    And gasp.. an actual answer to the question, without a rant about the STL :).

    Code:
    #include <iostream>
    #include <map>
    #include <algorithm>
    
    typedef std::pair<const int, int> mapitem;
    
    void printitem(mapitem& m) {
    	std::cout << m.first << ' ' << m.second << std::endl;
    }
    
    int main() {
    	std::map<int, int> squares;
    	for (int i = 0; i < 10; ++i) {
    		squares[i] = i*i;
    	}
    
    	std::for_each(squares.begin(), squares.end(), printitem);
    	return 0;
    }
    Prove you can code in C++ or C# at TopCoder, referrer rrenaud
    Read my livejournal

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Yes, yours is quite relevant, isn't it? Good example, too.
    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;
    }

  7. #7
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    Sorry guys but neither of those are functors.
    You see a functor is a class that has an overloaded operator () and neither of yours have.
    You need to overload operator () to do a map.erase() kuphryn erasing the mapitem pointed to by a passed iterator.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  8. #8
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    Thanks everyone.

    Here is one answer by Joaquín M López Muñoz of CodeProject.

    Code:
    class DeleteValue : public std::unary_function<std::pair<int const,char *>&, void>
    {
       public: 
          void operator()(std::pair<int const,char *> &pairObject)
          {
             delete [] pairObject.second;
          } 
    };
    Kuphryn

  9. #9
    geek SilentStrike's Avatar
    Join Date
    Aug 2001
    Location
    NJ
    Posts
    1,141
    I always thought of a functor as anything that acts like a function... they do too.

    http://www.codeproject.com/csharp/cs_functors.asp

    "One of the tools that an STL-programmer must learn to master is the functor concept. A functor is any valid expression that can be syntactically written as a function call. Those expressions can be functions, function pointers and operator() overloading."
    Prove you can code in C++ or C# at TopCoder, referrer rrenaud
    Read my livejournal

Popular pages Recent additions subscribe to a feed