serialize std::function with variable parameters - c++

my question is somewhat related to this question: Serialize C++ functor, but still different. It is a followup to this question: Passing a closure as a parameter to a constructor c++
Basically I have code that looks like this:
#include <iostream>
#include <string>
#include <functional>
using namespace std;
class Event
{
public:
std::function<double()> func;
template <typename T>
Event(T func): func(func) {}
virtual double execute()
{
double endtime = func();
return endtime;
}
};
double foo(int v1, int v2)
{
return(v1/(v2 * 1.0));
}
int main(int argc, char* argv[])
{
int a = 3;
int b = 4;
Event* e = new Event([=]() -> double{return foo(a, b);});
cout << e->execute() << endl;
int y;
std::cin >> y;
}
Is there a way to serialize func? I'd like to be able to save and load the function pointer AND the values to the parameters that the function it points to needs.
the output of the above is:
0.75
I'm using MSVS 2012, but would consider changing to MSVS 2013 if an answer requires features only available in the latter.

Related

std::function & std::forward with variadic templates

Recently I was reading about variadic templates and based on an example I've seen online I was trying to implement a basic event-system. So far it seems to work fine but I was trying to go a step further and allow N number of arguments to be passed to an event handler function / callback, unfortunately the build error I'm getting is the following and I'm not sure what I'm doing wrong. I looked into similar source codes but still cant figure out what's the issue.
D:\Development\lab\c-cpp\EventEmitter3\src\main.cpp:30:68: error: parameter packs not expanded with '...':
return std::any_cast<std::function<R(Args)>>(eventCallback)(std::forward<Args>(args)...);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Development\lab\c-cpp\EventEmitter3\src\main.cpp:30:68: note: 'Args'
Build finished with error(s).
Here is what I have so far, if you remove the ... the event system works fine for the 2 registered events in main.
#include <any>
#include <string>
#include <iostream>
#include <functional>
#include <unordered_map>
class EventEmitter
{
private:
std::unordered_map<std::string, std::any> events;
public:
EventEmitter() {}
void on(const std::string &eventName, const std::any &eventCallback)
{
events[eventName] = eventCallback;
}
template <typename R>
R emit(const std::string &eventName)
{
const std::any &eventCallback = events[eventName];
return std::any_cast<std::function<R(void)>>(eventCallback)();
}
template <typename R, typename... Args>
R emit(const std::string &eventName, Args &&...args)
{
const std::any &eventCallback = events[eventName];
return std::any_cast<std::function<R(Args)>>(eventCallback)(std::forward<Args>(args)...);
}
virtual ~EventEmitter() {}
};
int fun1()
{
std::cout << "fun1" << std::endl;
return 1;
}
double fun2(int i)
{
std::cout << "fun2" << std::endl;
return double(i);
}
double fun3(int x, int y)
{
std::cout << "fun3" << std::endl;
return double(x + y);
}
int main(int argc, char *argv[])
{
EventEmitter e;
e.on("fun1", std::function<int(void)>(fun1));
e.on("fun2", std::function<double(int)>(fun2));
e.emit<int>("fun1");
e.emit<double, int>("fun2", 1);
// Variadic would have been handy right here I guess?
// e.on("fun3", std::function<double(int, int)>(fun3));
// e.emit<double, int>("fun3", 1, 2);
return 0;
}
How can I fix this?
Well, you need to expand it.
return std::any_cast<std::function<R(Args...)>>(eventCallback)(std::forward<Args>(args)...);
^^^^^^^

Virtual function with unkown parameter vector type

I am trying to build an optimization library in C++ for parameters optimization.
The problem and the parameters type may vary, e.g. if the problem is to minimize the Ackley Function, then we have a vector<double> of size 2 (index 0 for the x, and index 1 for the y). However, we may have problems where the parameters are integers, or even strings.
Many algorithm exist for this type of optimization, like Genetic Algorithm, Differential Evolution, etc. In most of them, once we modify the parameters based on their optimization strategy, we have to call an evaluation function that receives the parameters, and given a objective function, will return a value (fitness).
My question is how could I implement an abstract class Problem in C++ such that it contains an virtual double evaluate function in which receives as reference a vector of the generic type of the related problem? For example, user's problem should inherit Problem and he needs to specify a type T, in this case, the evaluation function should be like virtual double evaluate(const vector<T> &parameters){}.
If the strategy which I mentioned above is not feasible for C++. Please, suggest alternatives strategies.
Based on #Quentin comment and your details I would say that you could first declare Problem as a class template
#include <vector>
#include <typeinfo>
#include <iostream>
using namespace std;
template<class T>
class Problem
{
public:
Problem() {
if(typeid(T) == typeid(double)){
cout << "The problem is of type double" << endl;
}
}
virtual double evaluate(const vector<T> &decisionVariables) = 0;
};
Then you can inherit from it and override the evaluate function based on your needs. Since you mentioned Ackley Function, I implemented an AckleyFunction which inherits from Problem with type double
#include "problem.h"
#include "math.h"
using namespace std;
class AckleyFunction : public Problem<double>
{
public:
AckleyFunction() {}
double evaluate(const vector<double> &decisionVariables) override {
const double x = decisionVariables[0];
const double y = decisionVariables[1];
return -20 * exp(-0.2 * sqrt(0.5 * (pow(x, 2) + pow(y, 2)))) - exp(0.5 * (cos(2 * M_PI * x) + cos(2 * M_PI * y))) + exp(1) + 20;
}
};
The global minimum for the Ackley function is x = 0, and y = 0. You can see that bellow in the main.cpp
#include <ackleyfunction.h>
#include <memory>
using namespace std;
int main(int argc, char *argv[])
{
shared_ptr<Problem<double>> prob(new AckleyFunction());
vector<double> decisionVariables = {5.1, 3.3};
cout << "Value at coordinates (5.1, 3.3): " << prob->evaluate(decisionVariables) << endl;
decisionVariables = {0., 0.};
cout << "Value at coordinates (0.0, 0.0): " << prob->evaluate(decisionVariables) << endl;
}
Output:
The problem is of type double
Value at coordinates (5.1, 3.3): 12.9631
Value at coordinates (0.0, 0.0): 0
Would something like this do?
#include <memory>
#include <iostream>
#include <vector>
class Problem {
public:
virtual double evaluate() = 0;
};
class MyProblem : public Problem {
public:
MyProblem(const std::vector<float>& parameters) : mParameters(parameters) {}
double evaluate() override {
// Do evaluation based on mParameters
return 47.11;
}
private:
const std::vector<float>& mParameters;
};
int main() {
std::vector<float> v = {1.0f, 2.0f};
std::unique_ptr<Problem> p{new MyProblem(v)};
std::cout << p->evaluate() << '\n'; // Calls MyProblem::evaluate()
return 0;
}

Passing overloaded constructor to function between classes

I have to put overloaded constructor form class Parameters into a function in class Solver.
Here is Parameters Header:
#ifndef Parameters
#define Parameters
#include <iostream>
#include<conio.h>
#include<fstream>
#include<string>
using namespace std;
class Parameters
{
int M;
double dx;
double eps;
public:
Parameters( );
Parameters(int M1, double dx1, double eps1 );
Parameters( string fileName);
};
#endif
The constructor initializes M, dx, eps with default values or chosen by the user from the keyboard or from the file.
I want to have another class which will be containing this initialized values (in order to solve some equation lately, also in this class).
The problem is that although I tried to do this by value, reference or/ pointers, there was always some error or code compiled but done nothing.
Here's my Solver class:
#include "ParametersH.h"
#include "EquationH.h"
#include <iostream>
#include<conio.h>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
class Solver
{
public:
int Solve( Parameters& obj );
};
int Solver::Solve( Parameters& obj)
{
cout << obj.M; // M is private so it fails :<
// another attempt was like this:
Parameters *pointer = new Parameters();
}
int main()
{
Solver Solve();
return( 0 );
}
I really couldn't handle this, hope someone will help.
As #lubgr mentioned in the comments, here
Solver Solve();
you declare a function named Solve() without parameters that give you a Solver object, not the member function Solve( Parameters& obj );
If your goal is to access private members of class Parameters in class Solver: You can either
define Solver a friend of Parameters: See here or
access through setters and getters or
make a struct of Parameters by which you can access everything inside
it
However, it looks like you only need a struct Parameters and a simple function Solve( Parameters& obj);, which will do your job.
struct Parameters
{
int m_;
double dx_, eps_;
Parameters(int M1, double dx1, double eps)
: m_(M1), dx_(dx1), eps_(eps) // provide other contrs as per
{}
};
int Solve(Parameters& obj)
{
std::cout << obj.m_ << " " << obj.dx_ << " " << obj.eps_ << std::endl;
return obj.m_;
}
now in the main() simply:
std::cout << "result: " << Solve(Parameters(1, 2.0, 3.0));

C++ Creating function map using templates and inheritance

I am trying to create a generic function map using templates.The idea is to inherit from this generic templated class with a specific function pointer type. I can register a function in the global workspace, but I'd rather collect all the functions together in the derived class and register these in the constructor. I think I am almost here but I get a compile error. Here is a stripped down version of my code:
#include <iostream>
#include <string>
#include <map>
#include <cassert>
using namespace std;
int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }
typedef int (*F)(int);
// function factory
template <typename T>
class FunctionMap {
public:
void registerFunction(string name, T fp) {
FunMap[name] = fp;
}
T getFunction(string name) {
assert(FunMap.find(name) != FunMap.end());
return FunMap[name];
}
private:
map<string, T> FunMap;
};
// specific to integer functions
class IntFunctionMap : public FunctionMap<F> {
public:
int f2(int x) { return 2 * x; }
int g2(int x) { return -3 * x; }
IntFunctionMap() {
registerFunction("f", f); // This works
registerFunction("f2", f2); // This does not
}
};
int main()
{
FunctionMap<F> fmap; // using the base template class directly works
fmap.registerFunction("f", f);
F fun = fmap.getFunction("f");
cout << fun(10) << endl;
return 0;
}
The error I get is:
templatefunctions.cpp: In constructor ‘IntFunctionMap::IntFunctionMap()’:
templatefunctions.cpp:33: error: no matching function for call to ‘IntFunctionMap::registerFunction(const char [3], <unresolved overloaded function type>)’
templatefunctions.cpp:15: note: candidates are: void FunctionMap<T>::registerFunction(std::string, T) [with T = int (*)(int)]
Juan's answer is correct: member functions have an implicit first parameter, which is a pointer to the type of which they are a member. The reason your code fails to compile is that your map supports function pointers with type int (*)(int), but the type of f2 is int (IntFunctionMap::*)(int).
In the specific case that you show here, you can use std::function, which implements types erasure, to present free functions and member functions as the same type. Then you could do what you are trying to do. Note: this requires C++11.
#include <iostream>
#include <string>
#include <map>
#include <cassert>
#include <function>
#include <bind>
using namespace std;
int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }
typedef std::function<int (int)> F;
// function factory
template <typename T>
class FunctionMap {
public:
void registerFunction(string name, T fp) {
FunMap[name] = fp;
}
T getFunction(string name) {
assert(FunMap.find(name) != FunMap.end());
return FunMap[name];
}
private:
map<string, T> FunMap;
};
// specific to integer functions
class IntFunctionMap : public FunctionMap<F> {
public:
int f2(int x) { return 2 * x; }
int g2(int x) { return -3 * x; }
IntFunctionMap() {
registerFunction("f", f); // This works
registerFunction("f2", std::bind(&f2, this, _1)); // This should work, too!
}
};
int main()
{
FunctionMap<F> fmap; // using the base template class directly works
fmap.registerFunction("f", f);
F fun = fmap.getFunction("f");
cout << fun(10) << endl;
return 0;
}

C++ : unresolved overloaded function when using function pointers

#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
The above code has a class B inside a class A, and class A has a method taunt that takes a function as an argument. class B's getMsg is passed into taunt...The above code generated the following error message: "error: no matching function for call to 'A::taunt()'"
What's causing the error message in the above code? Am I missing something?
Update:
#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (B::*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
t.cpp: In member function 'void A::run()':
Line 19: error: no matching function for call to 'A::taunt()'
compilation terminated due to -Wfatal-errors.
I'm still getting the same error after changing (*msg)(int) to (B::*msg)(int)
b.getMsg is not the correct way to form a pointer to member, you need &B::getMsg.
(*msg)(1) is not the correct way to call a function through a pointer to member you need to specify an object to call the function on, e.g. (using a temporary) (B().*msg)(1).
The right way to do such things in OOP is to use interfaces so all you need to do is to define an interface and implement it in B class after that pass the pointer of instance which implements this interface to your method in class A.
class IB{
public:
virtual void doSomething()=0;
};
class B: public IB{
public:
virtual void doSomething(){...}
};
class A{
public:
void doSomethingWithB(IB* b){b->doSomething();}
};
This works in VS 2010. The output is the same on all lines:
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int foo(int a, float b)
{
return int(a*b);
}
};
int main(int argc, char* argv[])
{
A temp;
int x = 5;
float y = 3.5;
auto a = std::mem_fn(&A::foo);
cout << a(&temp, x, y) << endl;
auto b = std::bind(a, &temp, x, y);
cout << b() << endl;
auto c = std::bind(std::mem_fn(&A::foo), &temp, _1, y);
cout << c(5) << endl;
}
Basically, you use std::mem_fn to get your callable object for the member function, and then std::bind if you want to bind additional parameters, including the object pointer itself. I'm pretty sure there's a way to use std::ref to encapsulate a reference to the object too if you'd prefer that. I also included the _1 forwarding marker just for another way to specify some parameters in the bind, but not others. You could even specify everything BUT the class instance if you wanted the same parameters to everything but have it work on different objects. Up to you.
If you'd rather use boost::bind it recognizes member functions and you can just put it all on one line a bit to be a bit shorter: auto e = boost::bind(&A::foo, &temp, x, y) but obviously it's not much more to use completely std C++11 calls either.