CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Dec 2008
    Posts
    10

    STL Style function parameters?

    Hi,

    I really like how the STL allows you to toss in a struct with a certain function present and it will use it like a function pointer (i.e. the various operators for sorting routines etc).

    I'd like to use something similar myself, but the code is rather convoluted and I wasn't able to figure out how they are doing it so that I don't actually have to pass the type as a template parameter.

    Does anyone know the trick they use that allows it? Is it really just looking for a function pointer or is there some sort of magic template trick that is letting that happen. If I try to use templates, I have to declare the correct type ahead of time, which doesn't work for what I want to do with it (I want that function object to be used only for that one function, and it needs to maintain some state).

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: STL Style function parameters?

    Quote Originally Posted by e_torstenson
    Does anyone know the trick they use that allows it? Is it really just looking for a function pointer or is there some sort of magic template trick that is letting that happen. If I try to use templates, I have to declare the correct type ahead of time, which doesn't work for what I want to do with it (I want that function object to be used only for that one function, and it needs to maintain some state).
    The function template simply uses the object passed as if it were a function. If a function pointer is passed, then well and good. If a function object is passed, then operator() is overloaded, and it is also well and good. The template argument can be deduced from the type of the argument, whether function pointer or function object.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Nov 2006
    Posts
    1,611

    Re: STL Style function parameters?

    Is my last post on this thread the kind of information you're looking for?

    http://www.codeguru.com/forum/showthread.php?t=481203
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

  4. #4
    Join Date
    Dec 2008
    Posts
    10

    Re: STL Style function parameters?

    Very cool! Your solution is probably the same as the one I came up with, just a little different in terms of usage syntax:

    Code:
    #include <iostream>
    
    using namespace std;
    
    struct function {
            ostream &os;
            function(ostream& os) : os(os) { }
            void operator()(int a) { os<<a<<"\n"; }
    };
    
    class magic {
    public:
            int num;
            magic(int num) : num(num) { }
            template<class F>
            void Run(F fn) {
                    for (int i=0; i<num; i++) {
                            fn(i);
                    }
            }
    
    };
    int main() {
            magic m(20);
            m.Run(function(cerr));
            m.Run(function(cout));
    }
    For this trivial example, it works fine, and allows me to skip having to use template parameters at the calling end, which is a goal, since it makes it a bit more readable. Thanks to laserlight for clarifying the objective with STL...I've spent the time thinking of the typing at the class level, and not at the function level.

    PS I'm a little embarassed that I didn't see this post in my search though Hopefully, it's OK to have two similar threads.

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: STL Style function parameters?

    Actually, I have a related question. If I want to create a "task queue", where each task is a functor, there is a difficulty: Each functor must be of the same type in order to fit in an STL container, and the type must be recovered entirely before it can be run if you used something generic.

    Is there a typical solution to this dilemma? I know boost::variant addresses it to some degree, but that still only gives you a limited number of types to work with.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: STL Style function parameters?

    An inheritance hierarchy (e.g., a Task abstract base class) with polymorphism sounds like a reasonable solution.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: STL Style function parameters?

    That's the obvious one, yes. I was just hoping to avoid that if I could. I'd like an interface comparable to boost::thread, which has no such limitation of course. Plus, functors should typically be copyable, and there's problems making that assumption when using inheritance.....
    Last edited by Lindley; July 28th, 2009 at 01:46 PM.

  8. #8
    Join Date
    Dec 2008
    Posts
    10

    Re: STL Style function parameters?

    If you can use Boost, boost::function might work.

    The example at http://www.boost.org/doc/libs/1_39_0...html#id1849073 looks like it might apply. You could have a queue of boost::functions. This assumes that they all have the same parameters, of course...which might not be the case.

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: STL Style function parameters?

    That may be exactly what I want, thanks.

  10. #10
    Join Date
    Nov 2006
    Posts
    1,611

    Re: STL Style function parameters?

    It depends on what you really mean by "comparable to boost::thread" - or more specifically, what "comparable" means.

    A boost::function object becomes a type.

    You can't create a container, for example, like:

    list<boost::function *>;

    You must supply template parameters, which then limits you to whatever target object and function signature you've supplied.

    If you want want is a very generic container of functions to be called, such that entries in the container could perform a call to any object, and any member function signature, you'll have to wrap a generic object around the boost::function which itself is a non-template base with a virtual "callback" function.

    The good news, though, is that you can fashion the object representing the queue such that it's something like the boost::thread. My own operates this way:

    Code:
    QueProcessor q;
    
    AnyObject o;
    
    int p1 = 5;
    double p2 = 6.25;
    
    q.Call( o, &AnyObject::somefunc, p1, p2 );
    ..or many permutations like that.

    Internally, however, the queue container owned by QueProcessor must be based upon a virtual "callback" to perform the call.
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

  11. #11
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: STL Style function parameters?

    There's only going to be one possible function signature----returning void with no arguments. So long as boost::function narrows all possible types with this signature down to a single type, it'll do. If that's not what it does, I may still have trouble....

  12. #12
    Join Date
    Nov 2006
    Posts
    1,611

    Re: STL Style function parameters?

    That's true. If there's only one target class and a single function signature, then you do have a single type no matter what the actual function is, and a container of them is possible.

    That's also true of a simple functor, too, representing a member function call (in case you'd like to avoid boost for some reason)
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

  13. #13
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: STL Style function parameters?

    Let std::mem_fun? Nah, avoiding Boost isn't worth the hassle of dealing with those methods. By far the least intuitive part of the STL....

    EDIT: A mem_fun_t needs to have the class type as one of its template parameters anyway, so it's no good for my purpose. Does boost::function have any such hidden template parameter?
    Last edited by Lindley; July 28th, 2009 at 02:31 PM.

  14. #14
    Join Date
    Dec 2008
    Posts
    10

    Re: STL Style function parameters?

    I think boost::function will work for what you need. It's actually what boost::thread uses, which is why I suggested it:P

    To be sure, I would write a short cpp file to test it, though. Then, you could catch any surprises before you make changes to real code which later have to be undone.

  15. #15
    Join Date
    Nov 2006
    Posts
    1,611

    Re: STL Style function parameters?

    I was thinking of something simple like this when I said "simple functor"....

    Though boost::functions is applicable...

    Code:
    template <typename obj>
    class adapter
    {
     private:
    
     obj *callee;
     void ( *fptr )();
    
     public:
    
     explicit adapter( obj &c, void ( *f ) () ) : callee( &c), fptr( f ) {}
    
     void operator()()
        {
         (callee->*fptr)();
        }
    };
    
    
    template<typename obj>
    adapter<obj> 
    make_adapter( obj &o, void (obj::*f)() )
    {
     return adapter<obj>( o );
    }
    Usage is something like:

    Code:
    list<adapter<SomeObject> > flist;
    
    .....
    
    SomeObject myo;
    
    flist.push_back( make_adapter( myo, &SomeObject::func ) );

    Or, the class owning the queue would likely have a function "like" make_adapter which performed the submission, like:

    Que<SomeObject> q;

    q.Call( myo, &SomeObject::func );

    Or if there's always only the same myo, perhaps its....

    Que<SomeObject> q( myo );

    q.Call( &SomeObject::fund );

    Where myo is always the same instance for q.


    Notice the use of the make_adapter function.


    The issue is that any such template object is going to need parameters (objects can't deduce the parameters), but template functions can...hence the make_adapter to simplify application code interface.
    Last edited by JVene; July 28th, 2009 at 02:43 PM.
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured