I'm trying to learn how to best use the std::function and the std::bind facilities
in the standard library - I'm interested in the TR1 versions, as that's what I
have available for now and I'm not aware of the differences, if any, between the TR1 implementations and the C++11 ones.
So for the sake of the exercise I've set up to construct a simple let's say "dispatcher".
What I want is to be able to execute any function from the dispatcher based on some decisions taken later at runtime. I set up my class to have a general function data
member like so:
class PoorDispatcher
{
...
private:
std::tr1::function<void()> m_f;
}
Then I assign to the data member the function I really want to call, similar to the below
...
m_f = std::tr1::bind(some_func, param1, param2, param3);
...
// then the call
m_f(); // SUCCESS
The above allows me to call successfully the function I want but I'm not sure it's the right thing to do. The questions:
Is the above usage scenario "sane"? Are there any better alternatives?
The above method poses a problem when trying to bind to a function which returns something. How can I retrieve the return value? (In my silliness I tired to cast the function objects without much success)
The template argument to std::function is the actual function type. void() means a function which takes no arguments and returns no value.
If you want to store a function that returns a value you have to create a new function object. Or if you are not sure if the function will return something, use boost.optional.
Related
I am relatively new to C++ and I am working on a personal project for practicing where I need to create a class that can take function pointers with different signatures.
The idea is that each instance of the class will store a pointer to a specific function and can call that function whenever I want.
To give a better idea of what I want, let me explain with a little bit more detail what I am trying to do. The project I am working on is a very basic console game and the object I am trying to create is an object that would store details on each location the player can access in the game.
(DISCLAIMER: I know that most of what I describe later is probably an overkill for a basic console game. I can easily make the whole game in a couple of files using just simple functions and I know how to do that. But the idea here is that I wanted to practice more advanced C++ techniques without having to figure out a complex project. So, since I know how to make a basic console game, I thought it would be a good idea to try and figure out how to achieve the same result but with more advanced techniques)
One of the details that I think should be stored is what happens in each location, basically the text that is output to the screen describing what happens and prompting the user to take action.
Since this would be different for each location, I can't just declare and implement a function in the class.
One way of solving this issue is to create a base class with a virtual function and then implement this function in a series of derived classes, each defining a new location.
The problem I have with this approach is that it makes each location a class that can be inherited further and instanced, which I don't need as I will only have 1 instance of each location.
I can of course just create 1 instance of the class, but I wanted to see if there is a way to avoid having to create separate classes for each location.
This why I started thinking of function pointers.
Now, I know I can declare a function pointer and initialise it in a class like that:
class Test
{
public:
Test(void (*p)())
: print{p}
{}
private:
void (*print)();
};
That works fine as long as the function returns void and accepts no arguments.
So, I thought maybe I can do that with a template:
template <typename Function>
class Test
{
public:
Test(Function *p)
: print{p}
{}
Function *print;
};
This actually works well. I can now have a class that accepts different functions with different return types.
I can create instances of the class in the following way:
void print();
Test<void ()> a {print};
However, I have one problem with this approach. Because it is a class template, I can't have a pointer that I want to use to point to instances of Test class regardless of the function that is passed to them.
For instance, if I declare the following pointer:
Test<void ()> *b = &a;
There is no way to re-assign that pointer to another instance of Test class unless the function pointer passed to it also returns void and accepts no arguments. Otherwise, I have to create a new pointer.
Is there a way to avoid that? Is there a better way of achieving what I am looking for than using function pointers?
Thank you very much and sorry for the long message.
There is no way to re-assign that pointer to another instance of Test class unless the function pointer passed to it also returns void and accepts no arguments.
And how would you expect that to work? Each Test has a different signature for its print method. In the example below, if you assigned action2 to action1, then how would it know what to pass to the print function?
void fun1() {}
void fun2(int) {}
void test() {
Test<void()> action1= &fun1;
action1.print();
Test<void(int)> action2= &fun2;
action2.print(42);
}
What you want is really simple, thanks to improvements in C++11: std::function<void()>.
Whenever you need to pass some arguments to the function, you'd use a lambda, potentially with captures:
#include <functional>
void fun1() {}
void fun2(int) {}
using Action = std::function<void()>;
int main() {
class MyObject { public: void doSomething() {} } obj;
Action action1;
action1 = fun1;
action1 = []{ fun2(42); };
action1 = [&obj]{ obj.doSomething(); }; // obj captured by reference
}
So that's pretty much what you should do.
Now of course you may ask "hey, but what if I wanted to implement something like std::function myself"? It's not a trivial task, if you want to get full functionality of std::function, including small object optimization (i.e. std::function usually doesn't allocate unless the functor it wraps is "big").
I wanted to see what can I do if I had a reason to have the each game location using a function that have different return types.
You chose to use a common abstraction, i.e. some class (like Action) that you can always call the same way, and get to do various things. So, what would you like the following code to do?
Action someAction;
int result = someAction();
std::string result = someAction();
Now suppose that e.g. someAction has captured a void() function. What should the code that assigns the "result" to an integer or a string do? And how would you protect from mistakes, e.g. if you really wanted someAction() to return an int, but you accidentally used one that returns nothing?
Remember that the compiler has to generate code for all of the sites where you call someAction, so it needs to know what to do ahead of time, even if you may otherwise ensure that no "incorrect" calls are made.
You could implement a custom Action class on top of std::function that could support std::optional<ResultType> instead of ResultType. That way, if the actual result of the functor wrapped in Action was convertible to that ResultType, you'd get a non-null optional, otherwise the optional would be null. And the list of supported result types would need to be pre-determined, i.e. the compiler wouldn't be able to dynamically add them, but adding a new type should amount to passing an additional type as a template argument, so it'd be easy to support quite many types.
I'm currently learning game development with c++ in Unreal Engine and I came across the function that takes a function pointer as an input:
InputHandle->BindAction("Grab",IE_Pressed, this, &UGrabber::Grab);
From basic C++ I know that in passing a function pointer as an attribute (UGrabber::Grab) - & is optional, however UEngine complains with the following error code if I omit the &:
error C3867: 'UGrabber::Grab': non-standard syntax; use '&' to create a pointer to member
Could someone explain why?
BindAction function declaration looks like this:
FInputActionBinding& BindAction( const FName ActionName, const EInputEvent KeyEvent, UserClass* Object, typename FInputActionHandlerSignature::TUObjectMethodDelegate< UserClass >::FMethodPtr Func )
The BindAction function makes use of a Dynamic Multicast Delegate.
They are one of Unreal's ways of having callback functions. In this case, they rely not just on calling a function, but calling a specific object's function. This is why you need to bass the third parameter (in this example, the parameter is this).
What it's saying is, when the input action is IE_Pressed, call the UGrabber function Grab on object this (this has to be a UGrabber instance of course). This is why it's a pointer to the method. It actually utilizes Unreal's reflection system to find the method on the object. So the this object needs to be UObject, otherwise you can't call a funciton on an object by name in C++.
For more info on this, search for "unreal delegates" and "unreal reflection" in your search engine of choice. Using them is quite easy, and it's not necessary to understand the reflection system to reliably use them. Just don't forget to bind and unbind at the appropriate times.
p.s. You can get quite in depth in this subject of callbacks you want. There are other delegate types that don't rely on reflection, for example non-dynamic delegates, that can bind to lambda functions, and or a more familiar if you're coming from a pure C++ background, where commonly a void* opaque is used, expected to be cast to the needed class pointer.
Background:
I have a Framework where I work on Objects. Up till now I created Objects in the framework with a default constructor. Now I want to introduce some customization on creation of the Objects. I decided it would be nice to allow to pass a factory into the Framework. I call it Provider, I will explain why below.
The only thing I expect in the Framework is to have a thing that will behave something like this
template< typename Provider >
void Framework::make_objects( Provider obj_provider)
{
Object obj = obj_provider();
}
I would like Provider to be anything that is callable, and returns an Object to be passed. E.g:
Factory factory;
framework.make_objects( factory.make_object ); // [1] a Factory method
framework.make_objects( []() { return Object(); } ); // [2] lambda
framework.make_objects( function_that_spits_Object ); // [3] a simple function
I call Provider a provider, and not a factory, because it is more of just a method of a factory.
Problem:
I cannot figure out a way with a simple front-end interface to pass and possibly store any kind of callable object (with a given signature). Is it possible?
What I tried:
I tried std::function, and got it to work, but gets really ugly when I want to provide Objects using a Factory method because it is overloaded, and a member method. So I need to bind factory instance to an overloaded member method. Possible but really ugly from the user side.
I think a template similar to the one Background example, would work, but it would be extremely nice to be able to store and pass the Provider. And I couldn't figure out how the template should be written to allow that.
I know that I can resolve my background/original problem, I could accept a whole Factory in the Framework, and write a constructor that would accept std::function and wrap it, so the function-type providers would implicitly get converted to Factory.
However my question for here is, is this possible to implement, to accept and store any kind of callable object, so I can just use provider() any where in the framework whenever I need a new object. This is the technical issue I am interested in here.
You can just put the member call inside the lambda, e.g. [factory] { return factory.make_object(); }. std::function is the solution here.
The problem that binding member functions sucks has nothing to do with what you're going to do with the result- there's no class or type you can use that can solve the problem of producing a wrappable function object in the first place. The syntax of f(factory.make_object) is impossible to support for any type.
Just use a lambda to wrap the member function and use std::function.
I would like to make an alias in C++ to singleton calling
so instead of calling MYCLASS::GetInstance()->someFunction(); each time, I could call just someFunctionAlias(); in my code.
Use a static function.
namespace ... {
void someFunction() {
MYCLASS::GetInstance()->someFunction();
}
};
Edit: Sorry lads, I wrote static someFunction and meant void someFunction.
typedefs are used for type aliases but can't be used as call alias.
functions (such as suggested as by DeadMG) can be used as a call "alias".
PS. As this is C++ you have lots of options, function pointers, std::tr1::function<> operator overloading and the preprocessor. But in this case it certainly looks like a simple function would be the simplest and best solution.
Look up function pointers.
You can create a function pointer, and assign it to your long function. You can then call this function pointer just like a regular function, wherever your variable is defined.
Function pointers can be confusing, but are used a lot in API callbacks (i.e. you pass a function as an argument to the API, and the API will call that function when something happens (think WndProc)).
Good luck.
you can do this
#define someFunctionAlias MYCLASS::GetInstance()->someFunction()
I have a class that uses functors as units of work. It accepts a reference to a functor in its Run() method. To allow this class to operate on any functor, all these functors must derive from my base functor class which looks like this:
class baseFunctor{
public:
virtual void operator()()=0;
virtual baseFunctor Clone()=0;
};
This works, however obviously it restricts these functors to having an operator method that returns void and accepts no parameters. I need to be able to accept a functor in my class that can take any type of parameters and return anything. Its apparently do-able but I can't seem to find a way to do it. I have considered using templates, multiple inheritance, but I keep getting thwarted by the fact that the class that needs to run this functor must be able to accept any type, so will accept the base class type, and so will not know the actual type of the functor.
Any suggestions of what avenue to look at would be appreciated.
How will the class that calls the functor know what parameters to provide and what to do with the return value, if any?
So, if I'm reading this right, you have a "Visitor pattern." It might be a good thing for you to look up.
Someone needs to know what type the functor is to give it arguments. Often with functors, the arguments are assigned to fields of the derived class, and operator() will operate on those fields. That is, the dumb method that calls the functor and doesn't know anything about it is given the closure (method plus arguments all in one class) by someone more knowledgeable.
If you do want generic functors that take multiple arguments in the operator(), templating will get you partway there, but you'll need one per arity.
I agree with Neil. Your main class has to know what parameters to pass and what return value to expect from these functors. Can you just type-cast your "functor" to an appropriate class that supports the function with the necessary arguments and return value?
class baseFunctor
{
};
class functor1x2: public baseFunctor
{
public:
virtual void* execute(void*, void*);
}
class MainClass
{
public:
void Execute(baseFunctor* ipFunctor)
{
functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
if(lpFunctor1x2)
{
lpFunctor1x2->execute(NULL, NULL);
}
}
}
I'm not sure what could be accomplished with this approach that couldn't more easily be accomplished with the Visitor pattern, as Drew noted.
If you are open to using the Boost library (www.boost.org), you might find Boot.Bind and Boost.Function of particular interest. I have used them in the past to achieve something very much along the lines of what you are discussing.
If you use Boost.Bind, you can perform currying on the functors to account for differences between the number of arguments the functor expects and the number of arguments the Run method expects (i.e., zero). The code that creates the functor would have to bind any arguments to specific values and thus create a zero-argument functor that can be passed to Run().
MV
Why'd you want to return the functor? Are you storing some state as well? Some more detail will be much appreciated since it is not very clear what exactly you want to do.
If you plan to use inheritance, do look up Covariant Return Types (and the Virtual Constructor idiom).
Now, for the meat of the problem: the problem is really not with passing in a functor but with functor application. You may want to take a look at boost::lambda and boost::parameter as well.
I think you want an ellipsis argument, like varargs for C++.
Perhaps std::tr1::function is interesting for you?