I would like to define a new function in muParser Link.
The FunctionWrapper-Class should be registrated.
class FunctionWrapper
{
public:
virtual double Evaluate(const double*, int) = 0;
};
The DefineFun-Method needs a string and a function pointer. How can I make this pointer to the function Evaluate?
I would like to call the DefineFun in an other class... something like this:
bool OtherClass::RegisterFunction(std::string name, FunctionWrapper *wrapper)
{
fParser.DefineFun(name, wrapper->????);
}
THx
Have you considered std::function as your wrapper? In conjunction with std::bind or lambdas, it can probably do everything you need. E.g.,
#include <unordered_map>
#include <functional>
#include <exception>
#include <memory>
#include <string>
#include <iostream>
class Evaluator
{
public:
virtual ~Evaluator() {}
virtual double Evaluate( const double*, int ) = 0;
// ...
};
class Registry
{
public:
typedef std::function<double(const double*, int)> Fn; // For easier reading
class NameNotFoundException : public std::exception {};
void Register( const std::string& name, const Fn& fn )
{
_regMap[ name ] = fn;
}
void Call( const std::string& name, const double* const data, const int size )
{
auto it = _regMap.find( name );
if( it == _regMap.end() )
{
throw NameNotFoundException();
}
it->second( data, size ); // Call fn
}
private:
std::unordered_map<std::string, Fn> _regMap;
};
class EvaluatorImpl : public Evaluator
{
public:
double Evaluate( const double* const data, const int size )
{ /*...*/
for( int n=0; n < size; ++n )
std::cout << data[n] << '\n';
return 0;
}
// ...
};
int main()
{
std::shared_ptr<Evaluator> eval( new EvaluatorImpl() );
Registry reg;
// Could use a lambda here instead of std::bind
reg.Register( "Bob",
std::bind( &Evaluator::Evaluate, eval, std::placeholders::_1, std::placeholders::_2 ) );
const double data[] = { 1, 2, 3 };
int size = 3;
reg.Call( "Bob", data, size );
}
here a sample Code:
#include <functional>
#include "muParser.h"
class Evaluator
{
public:
virtual ~Evaluator() {}
virtual double Evaluate( const double*, int ) = 0;
// ...
typedef std::function<double(const double*, int)> Fn; // For easier reading
};
class EvaluatorImpl : public Evaluator
{
public:
double Evaluate( const double* const data, const int size )
{ return 0; }
};
void MyClass::test()
{
Evaluator *e = new EvaluatorImpl();
Evaluator::Fn fn = std::bind( &Evaluator::Evaluate, e, std::placeholders::_1, std::placeholders::_2 );
mu::Parser fParser;
fParser.DefineFun("test", fn);
}
I get no matching function for call to mu::ParserCallback::ParserCallback(std::function<double(const double*, int)>&, bool&)’ when I call DefineFun(string, T a_func)
Related
How can I create a variable of generalised std::function type that can take any callable objects? I can't use variadic templates because it'll create a family of different types, while I need a single type, so that I can take different [&] lambdas to a same array.
I did it with functors (example below) that produce std::function<void()>, but for this I have to create a functor for every set of arguments that my functions use. Now I want to use lambdas to bind arguments, but their type is tricky and I can't get different lambdas to the same array.
I understand that this will be very unsafe.
#include <iostream>
#include <vector>
#include <string>
using ChoiceArray = std::vector<std::function<void()>>;
int GetInt(int restriction);
class MenuFunctor {
private:
std::string output;
ChoiceArray arrayOfFunctions;
public:
MenuFunctor(std::string n_output, ChoiceArray n_arrayOfFunctions)
: output(n_output), arrayOfFunctions(n_arrayOfFunctions)
{ }
void operator()() const {
int selection;
std::cout << output;
selection = GetInt(int(arrayOfFunctions.size()));
arrayOfFunctions[selection]();
}
};
class OperationFunctor {
private:
std::function<void(std::vector<std::string>*)> func;
std::vector<std::string>* container;
public:
OperationFunctor(std::function<void(std::vector<std::string>*)> n_func, std::vector<std::string>* n_container)
: func(n_func), container(n_container)
{ }
void operator()() const {
func(container);
}
};
void Func1(std::vector<std::string>* container);
void Func2(std::vector<std::string>* container);
void Func3(std::vector<std::string>* container);
int main() {
std::vector<std::string> container;
std::vector<std::string>* containerAddress = &container;
OperationFunctor f1(Func1, containerAddress);
OperationFunctor f2(Func2, containerAddress);
OperationFunctor f3(Func3, containerAddress);
ChoiceArray Array = {f1, f2, f3};
MenuFunctor Start("input 0-2\n", Array);
Start(); // Works
return 0;
}
Also, I tried to take std::vector<std::string> container for Func1-Func3 by reference, but it didn't work, so I went with pointers. It has something to do with perfect forwarding?
Just stuff lambdas into std::function<void()>.
using OperationFunctor = std::function<void()>;
using ChoiceArray = std::vector<OperationFunctor>;
int GetInt(int restriction);
class MenuFunctor {
private:
std::string output;
ChoiceArray arrayOfFunctions;
public:
MenuFunctor(std::string n_output, ChoiceArray n_arrayOfFunctions)
: output(n_output), arrayOfFunctions(n_arrayOfFunctions)
{ }
void operator()() const {
int selection;
std::cout << output;
selection = GetInt(int(arrayOfFunctions.size()));
arrayOfFunctions[selection]();
}
};
void Func1(std::vector<std::string>* container);
void Func2(std::vector<std::string>* container);
void Func3(std::vector<std::string>* container);
int main() {
std::vector<std::string> container;
std::vector<std::string>* containerAddress = &container;
OperationFunctor f1([containerAddress]{ Func1(containerAddress) });
OperationFunctor f2([containerAddress]{ Func2(containerAddress) });
OperationFunctor f3([containerAddress]{ Func3(containerAddress) });
ChoiceArray Array = {f1, f2, f3};
MenuFunctor Start("input 0-2\n", Array);
Start(); // Works
return 0;
}
Suppose I have this code all set up:
class Function
{
public:
virtual double eval(double x) const =0;
};
class Polynomial : public Function
{
private:
std::vector<double> coefficients;
public:
// ...
};
class CompositeFunction : public Function
{
private:
char operation;
Function* left;
Function* right;
public:
// ...
};
CompositeFunction operator+(Function& f, Function& g) {
return CompositeFunction('+',&f,&g);
}
Now, I'm trying to do the following thing:
CompositeFunction f = Polynomial({1,2}) + Polynomial({3,2});
printf("%lf\n",f.eval(1));
I don't get any compilation errors but when I try to eval f, Valgrind tells me I'm acessing bad data. I always get the correct answer but this is bugging me off.
I have tried to stop using stack-allocated arguments but I can't overload any pointer operation.
Is there any pointer-less way or friendly for the users of these classes?
It's because f has references to two temporary objects.
Expand it out to make it more obvious:
CompositeFunction f = operator+( Polynomial({1,2}), Polynomial({3,2}) );
f now holds references to the temporaries created by Polynomial({1,2}) and Polynomial({3,2}).
You might want to consider using std::function<double(double)> objects and lambdas, something like this:
#include <iostream>
#include <functional>
#include <vector>
typedef std::function<double(double)> Function;
Function polynomial(std::vector<double> const &coefficients) {
return [coefficients](double x) {
return x * coefficients[0]; // dummy evaluation
};
}
Function add(Function f1, Function f2) {
return [f1, f2](double x) { return f1(x) + f2(x); };
}
int main() {
Function f = add(polynomial({3,4}), polynomial({1,2}));
std::cout << f(3.3) << std::endl;
}
Here it is with std::shared_ptr:
#include <iostream>
#include <functional>
#include <memory>
#include <vector>
class Function
{
public:
virtual double eval(double x) const = 0;
virtual double derivative(double x) const = 0;
virtual ~Function() {}
};
typedef std::shared_ptr<Function> FunctionPtr;
class Polynomial : public Function
{
private:
std::vector<double> coefficients;
public:
// ...
Polynomial(std::vector<double> c) : coefficients(c) {}
};
class CompositeFunction : public Function
{
private:
char operation;
FunctionPtr left;
FunctionPtr right;
public:
// ...
CompositeFunction(FunctionPtr l, FunctionPtr r) : operation('+'), left(l), right(r) {}
};
FunctionPtr operator+(FunctionPtr f, FunctionPtr g) {
return std::make_shared<CompositeFunction>(f, g);
}
int main() {
auto p1 = std::make_shared<Polynomial>(std::vector<double>{1.0, 2.0});
auto p2 = std::make_shared<Polynomial>(std::vector<double>{3.0, 4.0});
auto f = std::make_shared<CompositeFunction>(p1, p2);
auto f2 = p1 + p2;
std::cout << f2->eval(3.3) << std::endl;
std::cout << f2->derivative(3.3) << std::endl;
}
This is a simple delegate class that only works for methods of the format void ClassType::MethodType( InputType& ), but can easily be expanded to more generic functions, not shown simply because it would be too large.
class Delegate
{
public:
Delegate( void ) : Object( NULL ), Argument( NULL ) { }
virtual ~Delegate( void ) { }
template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
void Create( ClassType* SetObject, void* SetArgument = NULL )
{
Object = SetObject;
Argument = SetArgument;
StaticCall = &CallMethod<ClassType, InputType, MethodType>;
}
template <class InputType>
inline void operator()( InputType InputValue ) const
{
(*StaticCall)( Object, static_cast<void*>(InputValue) );
}
inline void operator()( void ) const
{
(*StaticCall)( Object, Argument );
}
protected:
typedef void (*FunctionCallType)( void*, void* );
void* Object;
void* Argument;
FunctionCallType StaticCall;
private:
template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
static inline void CallMethod( void* SetObject, void* PassArgument )
{
(static_cast<ClassType*>( SetObject )->*MethodType)( static_cast<InputType>(PassArgument) );
}
};
It's flexible and can be used to pool callback classes, but one problem I have with it is that so far it's on par with (or even slower when used in large vectors like I plan to) than a virtual call if it's used as a base class. I'm looking for any suggestions on how to increase performance since I'm out of ideas, even if it affects functionality.
The simplest performance measuring code I used (with -O3) was:
class VirtualBase
{
public:
virtual void TestCall( int* Data ) {}
};
class VirtualTest : public VirtualBase
{
public:
VirtualTest() : Value(0) {}
void TestCall( int* Data )
{
Value += *Data;
}
private:
int Value;
};
class DelTest : public Delegate
{
public:
DelTest() : Value(0)
{
Create<DelTest, int*, &DelTest::TestCall>( this );
}
void TestCall( int* Data )
{
Value += *Data;
}
private:
int Value;
};
int main( int argc, char **argv )
{
clock_t start;
int Value = 1;
VirtualBase* NewBase = new VirtualTest;
start = clock();
for( size_t Index = 0; Index < 1000000000; ++Index )
{
NewBase->TestCall( &Value );
}
delete NewBase;
std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;
Delegate* NewDBase = new DelTest;
start = clock();
for( size_t Index = 0; Index < 1000000000; ++Index )
{
NewDBase->operator()( &Value );
}
delete NewDBase;
std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;
return 0;
}
I should mention that I'd like the class to stay non-template, as it makes classes using callbacks to anything easy to iterate through in a single vector.
You might want to look at this Lightweight Generic C++ Callbacks article on CodeProject
Some of the code from the linked article, showing the use of a function template to do the forwarding:
template<typename R, typename P1, typename P2>
class Callback
{
public:
typedef R (*FuncType)(void*, P1, P2);
Callback() : func(0), obj(0) {}
Callback(FuncType f, void* o) : func(f), obj(o) {}
R operator()(P1 a1, P2 a2)
{
return (*func)(obj, a1, a2);
}
private:
FuncType func;
void* obj;
};
template<typename R, class T, typename P1, typename P2, R (T::*Func)(P1, P2)>
R Wrapper(void* o, P1 a1, P2 a2)
{
return (static_cast<T*>(o)->*Func)(a1, a2);
}
class Foo
{
public:
float Average(int n1, int n2)
{
return (n1 + n2) / 2.0f;
}
};
float Calculate(int n1, int n2, Callback<float, int, int> callback)
{
return callback(n1, n2);
}
int main()
{
Foo f;
Callback<float, int, int> cb
(&Wrapper<float, Foo, int, int, &Foo::Average>, &f);
float result = Calculate(50, 100, cb);
// result == 75.0f
return 0;
}
There is also a great write up on stackoverflow here which will give you better insight.
I try to find a way to call functions depending on one String-Parameter.
Enums or Int are ok too for the Parametertype. Maybe there is something more ?
Is there a way to do it like this:
myFunction(string functionParameter, int value){
this->functionParameter(value);}
What is the best way for this? I know there are some similar Questions, but i didnt found a Answer that really fits my Problem.
Just use a map to map from strings to functions:
void f1()
{
std::cout << "f1!" << std::endl;
}
void f2()
{
std::cout << "f2!" << std::endl;
}
void f3()
{
std::cout << "f3!" << std::endl;
}
int main()
{
std::unordered_map<std::string,std::function<void()>> map;
map["f1"] = f1;
map["f2"] = f2;
map["f3"] = f3;
map["f1"]();
map["f2"]();
map["f3"]();
}
This outputs:
f1!
f2!
f3!
C++ doesn't have direct support to call functions using the name. You'll need to create the mapping somehow. The easiest approach is probably to create a map of a suitable std::function<...> type:
void f(int);
void g(int);
typedef std::function<void(int)> Function;
std:: map<std::string, Function> functions;
// ...
functions["f"] = f;
functions["g"] = g;
void call(std::string const& name, int x) {
auto it = functions.find(name);
if (it->second != functions.end()) {
it->second(x);
}
else {
// deal with unknown functions
}
}
You can map the string to the function pointer. Try something like this:
#include <iostream>
#include <string>
#include <functional>
#include <map>
class X;
template<class X>
class handler_factory;
template<>
class handler_factory<X>
{
private:
using HandlerType = void (X::*)(int);
public:
handler_factory();
HandlerType get(const std::string& name) const
{
if (handlers.find(name) == handlers.end())
return nullptr;
else
return (*handlers.find(name)).second;
}
private:
std::map<std::string, HandlerType> handlers;
};
class X
{
public:
friend class handler_factory<X>;
private:
void f(int);
void h(int);
};
handler_factory<X>::handler_factory()
{
handlers["f"] = &X::f;
handlers["h"] = &X::h;
}
void X::f(int) { std::cout << "X::f();"; }
void X::h(int) { std::cout << "X::h();"; }
Your class (in this example X) can have a function dispatch_method that looks like:
template<typename... Args>
void dispatch_method(const std::string& name, Args&&... args)
{
if (find_handler(name))
(this->*find_handler(name))(std::forward<Args>(args...));
}
Where find_handler is a helper method:
private:
auto find_handler(const std::string& name)
-> decltype(handler_factory<X>().get(name))
{
return handler_factory<X>().get(name);
}
Then you can call it like this:
int main()
{
X{}.dispatch_method("f", 5);
}
You may use something like:
#include <map>
#include <functional>
#include <stdexcept>
#include <string>
template<typename T> class Caller;
template<typename Ret, typename... Args>
class Caller<std::function<Ret(Args...)>>
{
public:
typedef std::function<Ret(Args...)> FuncType;
void add(const std::string& name, FuncType f)
{
functions[name] = f;
}
Ret call(const std::string& name, Args... args)
{
auto it = functions.find(name);
if (it == functions.end()) {
// Or any other error
throw std::runtime_error("unknown " + name + "function");
}
return (it->second)(args...);
}
private:
std::map<std::string, FuncType> functions;
};
So lets test it:
int minus(int a) { return -a; }
int main(int argc, char** argv)
{
Caller<std::function<int (int)>> caller;
caller.add("+1", [](int a) { return a + 1; } );
caller.add("minus", minus);
caller.call("minus", -42); // calls minus(-42), returns 42
caller.call("+1", 41); // calls the lambda, returns 42
return 0;
}
This is similar to question here. You need to create a map like this map<string, class::method>, then you can use its signature to search for function and call it.
Two ways are available for you:
1. Without using any 3rd-party library (in row C++):
#include <map>
#include <string>
struct Math
{
double sinFunc(double x) { return 0.33; };
double cosFunc(double x) { return 0.66; };
};
typedef double (Math::*math_method_t)(double);
typedef std::map<std::string, math_method_t> math_func_map_t;
int main()
{
math_func_map_t mapping;
mapping["sin"] = &Math::sinFunc;
mapping["cos"] = &Math::cosFunc;
std::string function = std::string("sin");
math_func_map_t::iterator x = mapping.find(function);
int result = 0;
if (x != mapping.end()) {
Math m;
result = (m.*(x->second))(20);
}
}
2. By using Boost library: The most convenient notation for method is function<signature> where function is either included in boost or in <utility>.
The signature would be like this.
map<string, function<double (double)> map; ...
map["sin"](1.0);
Basically, I have lots of differently typed structs like this:
typedef struct
{
char memberA;
int memberB;
...
} tStructA;
Is it possible to use a template to get/extract an arbitrary member from the struct? In pseudocode, I'm looking for something like this:
/*This is pseudocode!*/
template <typename STRUCT_TYPE, typename MEMBER_TYPE, membername NAME>
class cMemberExtractor
{
public:
MEMBER_TYPE
extract(const STRUCT_TYPE* pStruct) const
{
return pStruct->NAME;
}
};
The idea behind is to use the template like this:
/*somewhere*/
void
producer()
{
//produce update
tStructA* pUpdate=new tStructA;
...
//send update to receivers
emit(pUpdate);
}
/*elsewhere*/
void
consumer(const tStructA* pUpdate)
{
//extract data
int data=cMemberExtractor<tStructA,int,memberB>().extract(pUpdate);
//process data
...
}
Thanks for your help!
You can do that not with names but with member pointers:
template <typename C, typename M>
struct updater_t {
typedef M C::*member_ptr_t;
updater_t( member_ptr_t ptr, M const & new_value )
: new_value( new_value ), ptr(ptr)
{}
updater_t( member_ptr_t ptr, C & original )
: new_value( original.*ptr ), ptr(ptr)
{}
void operator()( C & obj ) {
obj.*ptr = new_value;
}
M new_value;
member_ptr_t ptr;
};
struct test {
int value;
};
int main() {
updater_t<test,int> update( &test::value, 10 );
test object;
update( object );
test object2;
updater_t<test,int> update_copy( &test::value, object );
update_copy( object2 );
}
Edit: Moving the member pointer to a template argument as suggested by litb:
template <typename C, typename M, M C::* Ptr>
struct updater_t {
updater_t( M const & new_value ) : new_value( new_value ) {}
updater_t( member_ptr_t ptr, C & original ) : new_value( original.*Ptr ) {}
void operator()( C & obj ) {
obj.*ptr = new_value;
}
M new_value;
};
int main() {
updater_t<test,int, &test::value> update( 10 );
test object;
update( object );
}
This works for me:
#include <iostream>
struct Foo {
int member;
Foo() : member() {}
};
template< typename T, typename C >
T& extract(C& obj, T C::* member)
{
return (obj.*member);
}
int main()
{
Foo foo;
std::cout << foo.member << '\n';
extract(foo, &Foo::member) = 42;
std::cout << foo.member << '\n';
return 0;
}
extract(Object, &Class::Member) returns a reference to Member in Object. Is that what you wanted?
You need help from macros.
#include <cstddef>
template <typename StructType, typename MemberType, size_t member_offset>
struct cMemberExtractor {
MemberType extract(const StructType* pStruct) const {
const char* member_loc = reinterpret_cast<const char*>(pStruct) + member_offset;
return *(reinterpret_cast<const MemberType*>(member_loc));
}
};
#define M_MEMBER_EXTRACTOR(STRU, MEMTYPE, MEMNAME) \
(cMemberExtractor<STRU,MEMTYPE,offsetof(STRU,MEMNAME)>())
...
int data = M_MEMBER_EXTRACTOR(tStructA,int,memberB).extract(pUpdate);
If your compiler supports the typeof operator, the MEMTYPE argument can be eliminated to help type safety.
#define M_MEMBER_EXTRACTOR(STRU, MEMNAME) \
(cMemberExtractor<STRU,typeof(((STRU*)0)->MEMNAME),offsetof(STRU,MEMNAME)>())
...
int data = M_MEMBER_EXTRACTOR(tStructA,memberB).extract(pUpdate);