Thread: Returning a function pointer from a function

  1. #1
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168

    Returning a function pointer from a function

    Here is my requirement:

    Assume I have functions a, b, and c all with the same signature.

    I need a, b, and c to *return* a pointer to either a, b, or c (based on some condition within each respective function)

    Is this possible? If so, could you show me a quick example?

    Edit:
    (What I'm really stuck on is the return type. I've tried using a typedef but that doesn't seem to get me any closer)

    Example:
    Code:
    typedef (*foo)(); // obviously doesn't work because no return type specified
    
    foo bar1()
    {
        if(yes){return &bar1; }
        else{ return &bar2; }
    }
    
    foo bar2()
    {
        if(yes){return &bar2; }
        else{ return &bar1; }
    }
    Last edited by StainedBlue; 11-01-2010 at 09:41 PM.
    goto( comeFrom() );

  2. #2
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    Function pointers are pesky little buggers - heck, there's a whole set of tutorials on them. Take a look here at the function pointer tutorials, there's a part about function pointer return values. (The rest is a good read, too, IMO)

    EDIT: Oops, looks like that didn't really get any farther than you were already.
    Last edited by bernt; 11-01-2010 at 10:02 PM.
    Consider this post signed

  3. #3
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Thanks, although, that's not quite what I'm looking for. I need to be able to specify sort of an anonymous type as the return type. Hard to explain but here's another example of what I'm trying to do, and it's really close to working I think:

    Code:
    #include <iostream>
    
    template <typename T>
    T a()
    {
    	std::cout << "In A";
    	return &b;
    }
    
    template <typename T>
    T b()
    {
    	std::cout << "In B";
    	return &a;
    }
    
    int main()
    {
    	void (*foo)();
    	foo = &a;             // compiler complains "mismatch in formal parameter list"
    	foo = *foo;
    	std::cout << "\n";
    	foo = *foo;
    
            return 0;
    }
    goto( comeFrom() );

  4. #4
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    Ok, some more google-fu turned up this paper. The conclusion is this, which is close to what you've got actually.
    A Correct and Portable Way

    Fortunately, we can indeed get exactly the intended effect required by Question #3 in a completely type-safe and portable way, without relying on nonstandard code or type-unsafe casting. The way to do it is to use a proxy class that takes, and has an implicit conversion to, the desired pointer type:
    Code:
      //  Example 3(d): The correct solution
      //
      struct FuncPtr_;
      typedef FuncPtr_ (*FuncPtr)();
    
      struct FuncPtr_
      {
        FuncPtr_( FuncPtr pp ) : p( pp ) { }
        operator FuncPtr() { return p; }
        FuncPtr p;
      };
    Now we can declare, define, and use f() naturally:
    Code:
      FuncPtr_ f() { return f; } // natural return syntax
    
      int main()
      {
        FuncPtr p = f();  // natural usage syntax
        p();
      }
    This solution has three main strengths:

    1. It solves the problem as required. Better still, it's type-safe and portable.

    2. Its machinery is transparent: You get natural syntax for the caller/user, and natural syntax for the function's own "return myname;" statement.

    3. It probably has zero overhead: On modern compilers, the proxy class, with its storage and functions, should inline and optimize away to nothing.
    Coda

    Of course, normally a special-purpose FuncPtr_ proxy class like this (that contains some old object and doesn't really care much about its type) just cries out to be templatized into a general-purpose Holder proxy. Alas, you can't just templatize the FuncPtr_ class above, because then the typedef would have to look something like:

    typedef Holder<FuncPtr> (*FuncPtr)();

    which is self-referential.
    Consider this post signed

  5. #5
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Ah! Many thanks! that worked like a charm!
    goto( comeFrom() );

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 04:25 AM
  3. Function returning pointer to function
    By DL1 in forum C++ Programming
    Replies: 6
    Last Post: 08-07-2009, 10:27 AM
  4. Replies: 0
    Last Post: 03-20-2008, 07:59 AM
  5. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM