I have an application that is creating maps for civilization V. As an interesting design choice I decided to create a couple of functions that would do the looping through the map for me. This way I could pass a function pointer or a lambda function to that function that goes through the whole map doing something to each tile. Reasoning behind this was if I or someone else would change the way the map is stored (from 2D array to a 2D vector or whatever) one would only need to change one function instead of the whole codebase.
Now the problem, here is some code first.
Error code.
case ALL_SNOW:
m.loop_through_limit([] (Tile* t) {
t = new Snow(t->get_x(), t->get_y());
return t;
}, x, y, width, height);
break;
case PTN_ONE:
m.loop_through_limit([&] (Tile* t) {
int cur_x = t->get_x();
int cur_y = t->get_y();
t = new Plains(cur_x, cur_y);
// if (y <= height/4 || y >= (height*3)/4) {
// Top quarter rows and bottom quarter rows
// t = new Ocean(cur_x, cur_y);
// } else if (cur_x <= width/4) {
// Leftmost columns
// t = new Ocean(cur_x, cur_y);
// } else if (cur_x >= (width*3)/4) {
// Rightmost columns
// t = new Desert(cur_x, cur_y);
// }
return t;
}, x, y, width, height);
break;
Definitions from header file.
void loop_through(void (*)(Tile* t));
void loop_through_limit(Tile* (*)(Tile* t), int start_x, int start_y, int width, int height);
Now the difference in each case isn't much apart from the commented out code. This works fine. When I comment out that if statement block, then this is my output.
c++ -c -g -O3 -ffast-math -Wall -Weffc++ -std=c++0x -o tile_block.o tile_block.cpp
tile_block.cpp: In static member function ‘static void TileBlock::write(Map&, TileBlock::Patterns, int, int, int, int)’:
tile_block.cpp:82:35: error: no matching function for call to ‘Map::loop_through_limit(TileBlock::write(Map&, TileBlock::Patterns, int, int, int, int)::<lambda(Tile*)>, int&, int&, int&, int&)’
tile_block.cpp:82:35: note: candidate is:
map.h:26:10: note: void Map::loop_through_limit(Tile* (*)(Tile*), int, int, int, int)
map.h:26:10: note: no known conversion for argument 1 from ‘TileBlock::write(Map&, TileBlock::Patterns, int, int, int, int)::<lambda(Tile*)>’ to ‘Tile* (*)(Tile*)’
And I believe the problem comes when I start using the parameters I'm trying to capture by reference. Then it starts to turn into a "lambda" function instead of just a "function pointer", maybe I'm just not getting it.
Any suggestions?
C++11 lambda are not function pointers if they capture variables. What you need is called std::function, especially for the second function, because the lambda for that capture variables.
So change these:
void loop_through(void (*)(Tile* t));
void loop_through_limit(Tile* (*)(Tile* t), /*...*/);
to these:
void loop_through(std::function<void(Tile*)> fun);
void loop_through_limit(std::function<Tile*(Tile*)> fun, /*...*/);
Now you can pass lambda to the above functions.
Lambdas are typically implemented as functors (objects with an overloaded operator()). For lambas without captures the standard guarantees that they are implicitely convertible to a function pointer with the same signature (safe, since the lambda functor doesn't contain data). For lambdas with capture that is not safely possible and therefore forbidden.
In order to allow for this you need to change your loop_through and loop_through_limit method to either take std::function<void(Tile*)>:
void loop_through(std::function<void(Tile*)>);
void loop_through_limit(std::function<Tile*(Tile*)> func, int start_x, int start_y, int width, int height);
or to a template function taking any type of executable function object
template<typename F> void loop_through_limit(F func);
template<typename F> void loop_through_limit(F func, int start_x, int start_y, int width, int height);
The later approach has the advantage of lower overhead (no need to construct a std::function object), while the former approach has the advantage of not making the method a template, so it can e.g. still be virtual.
...Then it starts to turn into a "lambda" function instead of just a
"function pointer"...
Thats exactly right, Standard says that lambdas that do not capture anything can be implicitly cast to function pointers with same signature.
That you can do is make loop_through and loop_through_limit templates
template <typename F>
void loop_through(F);
template <typename F>
void loop_through_limit(F, int start_x, int start_y, int width, int height);
and call f inside.
Related
I'm using ROOT Cern to solve a multi-variable non-linear system of equations. For some problems I have 4 functions and 4 variables. However, for others I need 20 functions with 20 variables. I'm using a class called "WrappedParamFunction" to wrap the functions and then I add the wrapped functions to the "GSLMultiRootFinder" to solve them. The function is wrapped this way:
ROOT::Math::WrappedParamFunction<> g0(&f0, "number of variables", "number of parameters");
Therefore, I need to declare the f0...fi functions before my void main(){} part of the code. I'm declaring the functions in this way:
double f0(const double *x, const double *par){return -par[0]+y[0]*par[1];}
double f1(const double *x, const double *par){return -par[1]+y[1]*par[2];}
.
.
Is there a way to create those functions inside a loop and stack them in an array? Something like this:
double (*f[20])(const double *x, const double *par);
for(int i=0;i<20;i++){
f[i]= -par[i]+x[i]*par[i+1];
}
So that later I can wrap the functions in this way:
ROOT::Math::WrappedParamFunction<> g0(f[0], "number of variables", "number of parameters");
f[i]= -par[i]+x[i]*par[i+1];
You can't generate code at runtime, so you can't do exactly what you're asking for.
You can however save the value of i for use at runtime, so you have a single callable object with a hidden parameter i not passed explicitly by the caller. The simplest example is
auto f = [i](const double *x, const double *par)
{
return -par[i]+x[i]*par[i+1];
};
but this gives a unique type to the lambda f, so you can't easily have an array of them.
You can however write
using Callable = std::function<double, const double *, const double *>;
std::array<Callable, 20> f;
and store the lambdas in that.
I think you'll need to use ROOT::Math::WrappedParamFunction<Callable> for this to work, though, since the FuncPtr parameter type is not erased.
If you really can't change the WrappedParamFunction type parameter for whatever reason, you can generate a free function instead of a stateful lambda using templates - but it's pretty ugly.
Edit - I was considering writing that version out too, but fabian beat me to it. Do note that you have to either write out all that machinery for each distinct function that needs this treatment, wrap it in a macro, or generalize everything to take a function template parameter as well.
There are almost certainly better ways of accomplishing this, but this probably gets you closest to the desired result described in the question:
Create a function template with the offset as template parameter and then create an std::array of function pointers with function pointers pointing to specializations of a template function. Note that the size of the array must be a compile time constant for this to work:
template<size_t Offset>
double f(const double* y, const double* par)
{
return -par[Offset] + y[Offset] * par[Offset+1];
}
template<size_t ... Offsets>
std::array<double(*)(double const*, double const*), sizeof...(Offsets)> CreateFsHelper(std::index_sequence<Offsets...>)
{
return { &f<Offsets>... };
}
template<size_t N>
std::array<double(*)(double const*, double const*), N> CreateFs()
{
return CreateFsHelper(std::make_index_sequence<N>{});
}
int main()
{
auto functions = CreateFs<20>();
}
Making your i a template parameter and generating the functions recursively at compile time can also do the trick:
using FunctionPrototype = double(*)(const double *, const double *);
template<int i>
double func(const double * x, const double * par) {
return -par[i]+x[i]*par[i+1];
}
template<int i>
void generate_rec(FunctionPrototype f[]) {
f[i-1] = &func<i-1>;
generate_rec<i-1>(f);
}
template<>
void generate_rec<0>(FunctionPrototype f[]) { }
template<int i>
FunctionPrototype* generate_functions()
{
FunctionPrototype * f = new FunctionPrototype[i]();
generate_rec<i>(f);
return f;
}
FunctionPrototype * myFuncs = generate_functions<3>(); // myFuncs is now an array of 3 functions
"Is there a way to create an array of functions inside a loop in C or C++"
sure, you can create a std::array or std::vector of std::function.
You can also create a container of function pointers if you so desire.
I'm trying to understand bind and pre-fill functions in C++.
Here's my example:
#include <iostream>
#include <functional>
#include <vector>
class Voice
{
public:
double mValue;
private:
};
class VoiceManager
{
public:
VoiceManager() { }
~VoiceManager() { }
typedef std::function<void(Voice &)> VoiceChangerFunction;
inline void UpdateVoices(VoiceChangerFunction callback) {
for (int i = 0; i < mNumOfVoices; i++) {
callback(mVoices[i]);
}
}
static void SetValue(Voice &voice, unsigned int value) {
voice.mValue = value;
std::cout << voice.mValue << std::endl;
}
private:
static const int mNumOfVoices = 4;
Voice mVoices[mNumOfVoices];
};
int main()
{
VoiceManager voiceManager;
VoiceManager::VoiceChangerFunction callback;
callback = std::bind(&VoiceManager::SetValue, std::placeholders::_1, 100);
voiceManager.UpdateVoices(callback);
}
Basically, I create a VoiceChangerFunction function (object) that takes a Voice & as first parameter and returns void.
Later, I bind a function that will take as first parameter the one I'll give to it when I call it, and another parameter that I give when I bind it (100, in my example).
Right?
What I don't understand is: then, this function is passed to UpdateVoices(), which take as input a function/object that has 1 param (Voice &), not 2 as created in my bind function (Voice &, unsigned int).
How can it works?
Its like to have void VoiceChangerFunction(Voice &voice) and call VoiceChangerFunction(Voice &voice, unsigned int value ).
The function prototype is different. I mean: the callback bind I created isn't a VoiceChangerFunctions function, because it takes more parameters.
How can it works/match?
That is exactly the beauty of bind and std::function at works. You are defining the callback as function taking one argument, and bind is returning a function object which takes one argument.
The main point here is that it actually calls the function which takes 2 parameters, but the second one is fixed, and will always be 100 (in your case). This is the sole purpose of binders - to provide a way to call functions with different set of arguments with some fixed values. If you would be calling the function taking the same set of arguments, there would be no reason to use binders at all!
Knowing that bind is similar to lambdas, the same code could be written as - and probably be more clear:
VoiceManager::VoiceChangerFunction callback;
callback = [](Voice& v) { VoiceManager::SetValue(v, 100); };
voiceManager.UpdateVoices(callback);
And if you are curious how it works, you might try to create a binder framework yourself. If you are only doing it for educational purposes and not worried about too many details, it is not that hard.
When you bind, you're making a new function that only takes Voice as a param, that's why it works.
void a_func(int x) { return; }
std::function<void(void)> new_func = std::bind(&a_func, 1);
new_func now has the signature of void(void), so you could pass it around to anywhere that expects a function of type void(void).
When you call new_func, it really calls a_func(1).
Your assumption about bind is wrong.
Your bind call returns a function object that will accept one parameter, namely the placeholder. The other parameter on your function is already bound to 100.
A little example:
void foo(int i1, int i2) {};
std::function<void(int,int)> fn1 = std::bind(foo, std::placeholders::_1, std::placeholders::_2);
std::function<void(int)> fn1 = std::bind(foo, std::placeholders::_1, 1);
std::function<void()> fn1 = std::bind(foo, 1, 1);
The bind will create a matching function depending on bound and unbound parameters.
Update
The compiler will generate a struct from the bind expression and a copy of your parameter. Simplified something like this(this will not compile):
struct Function_{
void(*fn)(Voice &, unsigned int)
unsigned int i_;
Function_(void(*f)(Voice &, unsigned int), unsigned int i):fn(f),i_(i){}
void operator()(Voice& v){
fn(v, i_);
}
}
fn is the first parameter which is a function pointer and the bound (100) is the second. Then all you need is some type erasure and your own bind is ready to go.
I am trying to pass parameters to a function pointer being passed as a parameter.
Code:
void Test(wchar_t* a, wchar_t* b)
{
// ...
}
void Test2(void(*Func)(wchar_t*, wchar_t*))
{
// ...
}
int main()
{
Test2(Test(L"Hello", L"Testing"));
return 0;
}
I am getting this error:
argument of type "void" is incompatible with parameter of type "void (*)(wchar_t *, wchar_t *)"
How do I fix this to accomplish what I'm trying to achieve?
Edit: Sorry for not being clear. What I'm actually trying to accomplish is inject a function into a child process and pass two parameters (wchar_t*, wchar_t*) so I can use them. But the main function can either be void or int argc, char** argv. So I accomplished what I'm trying to achieve by simply using global variables
You probably want to have something like
void Test2(void(*Func)(wchar_t*, wchar_t*),wchar_t* x, wchar_t* y)
{
(*Func)(x,y);
}
int main()
{
Test2(Test,L"Hello", L"Testing");
return 0;
}
instead.
As for your comment
How do i do this in C++ with templates?
I could think of
template<typename Param>
void Test2(void(*Func)(Param, Param), Param x, Param y) {
(*Func)(x,y);
}
void Test(wchar_t* a, wchar_t* b);
int main() {
Test2(Test,L"Hello", L"Testing");
return 0;
}
This should just work fine.
There are more than one way to fix tihs issue, however, let me just try to show why this error is occuring.
Every function has a type of value associated with it. This means, that every function evaluates to a value of some type. This is indicated by its return value.
For example:
int foo(/*whatever*/);
evaluates to an int. So foo(/*whatever*/) can be used anywhere an int is expected. For example like int a = b + foo(/*whatever*/).
Simlarly float bar(/*whatever*/); evaluates to a float, hence bar(/*whatever*/) can be used anywhere a float is expected. For example like float a = b + bar(/*whatever*/).
A function that returns void like void foobar(/*whatever*/) however, evaluates to void and cannot be used where a value of some type (say int, float, etc) is expected.
Now coming to code. This line in your main function has the issue:
int main()
{
Test2(Test(L"Hello", L"Testing")); /* Issue here */
return 0;
}
Here you are passing Test(L"Hello", L"Testing") as the argument to Test2. Now remember, that Test(/*whatever*/), evaluates to a void because Test returns a void.
So what you are doing in that line is something like
Test2(/*something that evaluates to a void*/);
However, Test2 expectes a void (*)(wchar_t*, wchar_t*), which is a pointer to a function that returns void, which is different from void.
So what is happening, is that the compiler is seeing that you are passing a void in a place where a void (*) (wchar_t*, wchar_t*) is expected, so it is correctly indicating that error.
There can be different ways to solve this issue which are mentioned in other answers.
Do I need to use C++ templates?
Of course, you can do that using C++ templates as it follows:
#include<utility>
// ...
template<typename F, typename... A>
void Test2(F &&f, A&&... a)
{
std::forward<F>(f)(std::forward<A>(a)...);
// ...
}
// ...
Test2(Test, L"Hello", L"Testing");
But you don't need them to do what you are trying to do.
#πάνταῥεῖ has already explained why in its answer.
I have the following code:
int main(int argc, char **argv)
{
App app(800, 600);
app.add_event_scene(Scene("Event Plot", event_plot));
Image x("sample.png");
struct foo { static void visual_plot() { x.draw(); } }; // Error.
app.add_visual_scene(Scene("Visual Plot", foo::visual_plot));
app.run();
return 0;
}
And I get the following error:
||=== Build: Debug in Joy-Plus-Plus (compiler: GNU GCC Compiler) ===|
G:\Development\Game-Development\CB\Joy-Plus-Plus\main.cpp|54|error: use of local variable with automatic storage from containing function|
G:\Development\Game-Development\CB\Joy-Plus-Plus\main.cpp|53|error: 'Image x' declared here|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
I'm writing a multimedia/game engine for the Allegro 5 library, and I've abstracted the drawing part of the main-loop (As well as the event parts) into "scene" objects with plots (Functions). Each procedure is passed to the App, so that it gets "run" inside the main-loop. The problem is, the "C++ approach" does not work:
Image x("sample.png");
void visual_plot()
{
x.draw(); // Problem.
}
int main(int argc, char **argv)
{
App app(800, 600);
app.add_event_scene(Scene("Event Plot", event_plot));
app.add_visual_scene(Scene("Visual Plot", visual_plot));
app.run();
return 0;
}
Although the code runs, this happens:
And if I put the x inside the visual_plot, the image is loaded normally:
But now I have a huge performance problem, since a new Image object is being created at each main-loop (And it's not long until the whole thing freezes).
The image is not found when I put it outside the scope of the function because it must come after the initialization of the App, but since I have a typedef function pointer in Scene that takes that function as an argument, I also must give it a void function. The problem is that I can't create local / nested functions in C++ (After the initialization of the App). So, in order to avoid the problem, I've tried the obvious (Lambda expression / closure):
int main(int argc, char **argv)
{
App app(800, 600);
app.add_event_scene(Scene("Event Plot", event_plot));
Image x("sample.png");
app.add_visual_scene(Scene("Visual Plot", [&x]()->void{x.draw();}));
app.run();
return 0;
}
The problem is that the second argument of the constructor of Scene takes a function pointer:
typedef void(*plot)();
typedef map<string, plot> act;
class Scene
{
private:
string name;
plot p;
public:
Scene(string name, plot p);
~Scene() {};
string get_name();
plot get_plot();
void set_name(string value);
void set_plot(plot value);
};
And since functions cannot be passed as parameters, and get decayed to pointers, the same also applies to the lambda expression (Which is not a function), so I get the following error:
G:\Development\Game-Development\CB\Joy-Plus-Plus\main.cpp|52|error: no matching function for call to 'Scene::Scene(const char [12], main(int, char**)::__lambda0)'|
Facing such a tragedy, how can I simulate a nested function in C++11? Since simulating like this answer does not work.
OBS: I agree that it could be a design problem, but I pretty much don't see it that way. For me, C++ just don't want me to pass that bloody function as a parameter by any means (So, I ask for the help of you long C++ Wizards).
Simply put the image inside the visual_plot function and make it static:
void visual_plot()
{
static Image img("sample.png");
x.draw(); // Problem.
}
This will initialize img the first time visual_plot is called, and only then. This will solve both the performance problem and the "it must be initialized after app.run()" issue.
It is a design problem. In order to accomplish what you are trying to do you need two pieces of information: the code to execute and the data to execute it against.
A lambda isn't magic, it simply encapsulates both of these into an object, that's why it doesn't decay nicely to a single function pointer. A lambda with captures is syntactic sugar for a function object:
int x, y;
float f;
// ...
auto l = [x, &y, f] () { return static_cast<int>((x + y) * f); };
int r = l();
is saving you from writing
struct Values {
int x;
int& y;
float f;
int operator() () {
return static_cast<int>((x + y) * f);
}
Capture(int x_, int& y_, float f_) : x(x_), y(y_), f(f_) {}
};
//...
Capture c(x, y, f);
int r = c();
That's a member function call at the end there, so two pointers are involved: a pointer to the member function 'operator()' and a pointer to the instance to call it on.
int r = Capture::operator=(&c); // pseudo
Using a static or global variable you could make the address of the data known at compile time and so allow yourself to only need a function pointer.
But your design is that of a strcpy that only takes one argument or a print function that takes none: how do you know what to copy or print?
Better designs would be either to let you pass a function object to the plot functions, see how STL predicates work, which would allow both function pointers and lambdas, or use virtual functions and subclassing.
struct Scene { virtual void plot(); };
struct MyScene : public Scene {
Image x;
MyScene() : x("image") {}
void plot() override { x.draw(); }
};
The pitfall of this approach is "slicing", you need to pass Scene by reference rather than by value if you are allowing derived types:
void foo(Scene& s) {
s.plot();
}
foo(MyScene(...)); // not going to go well
I am looking for and stuck on issue of passing class and structure instances as arguments to call back functions using boost::bind
So far call back using this method works fine.
I want to use shown below code snippets
class A
{
public :
static int i = 1;
};
However, I want to pass this class instance to this call back function pointer described below
void Init(void (*Notify)(A *a, int, int,int),int arr[],
A *a, value,int left,int right)
{
}
You cannot use Boost Bind directly to do this. Your Init function requires a pointer to a free function having this signature:
void (*)(A *a, int, int, int)
So you could implement one like this:
void foo(A *a, int x, int y, int z)
{
a->whatever(x, y, z);
}
You'd then call Init(foo, ...).
But it will have to be a free function; the somewhat equivalent Boost Bind expression will not work:
boost::bind(&A::whatever, _1, _2, _3)
Why won't this work? Because Init requires a free function, not e.g. a boost::function<void(A*,int,int,int>)> which would support boost::bind.