runtime specialization of overloaded function - c++

This is a variant of this SO question. I have an overloaded function that takes parameters of different types and returns different types:
struct mystruct {
auto f (int x, int y) -> int;
auto f (std::string x, int y) -> float;
};
The function f needs to call itself with one of its parameters specialized a number of times.
I'd like to define a function that specializes the parameter y, that is I'd want g(z) = f(z,y). The return type of g and the type of its unique parameter z variable, but the implementation is the same in both cases.
The best implementation I could find of this situation is overloading the lambda function:
template <class F1, class F2>
struct overload_set : F1, F2
{
overload_set(F1 f1, F2 f2) : F1(f1), F2(f2) {}
using F1::operator();
using F2::operator();
};
template <class F1, class F2>
overload_set<F1, F2> overload(F1 f1, F2 f2) {
return overload_set<F1, F2>(f1, f2);
};
struct mystruct {
auto f( std::string x, int y) -> float {
return y+9.3;
}
auto f( int x, int y) -> int
{
auto g = overload (
[=]( int z ) -> int {return f(z,y);},
[=]( std::string z) -> float { return f(z,y); }
);
if ( x == 0 ) {
std::cout << g("this string") << "\n";
return 0;
}
if ( x == 1 ) return y;
return 7;
}
};
int main () {
mystruct h;
std::cout << h.f(1,4) << "\n";
std::cout << h.f(0,2) << "\n";
}
which works as expected but seems overkill. It seems that a simple preprocessor macro of the form
#define k(z) f(z,y)
would also work. Is there a good way of achieving this?

Not sure if this is what you are attempting to do but here is a working (c++14) example:
#include <iostream>
struct mystruct {
static auto f (int x, int y) -> int {
std::cout << "f(" << x << "," << y << ")" << std::endl;
auto g = [=](auto z) -> decltype(mystruct::f(z, y)) {
return mystruct::f(z, y);
};
if (x < 1)
g("end");
else
g(x - 1);
}
static auto f (std::string x, int y) -> float {
std::cout << "f(\"" << x << "\"," << y << ")" << std::endl;
}
};
int main() {
mystruct::f(10, 1);
}
Output:
f(10,1)
f(9,1)
f(8,1)
f(7,1)
f(6,1)
f(5,1)
f(4,1)
f(3,1)
f(2,1)
f(1,1)
f(0,1)
f("end",1)

Am I missing something?
This produces the same answer, and I think is a little clearer:
#include <string>
#include <iostream>
struct mystruct
{
auto f( std::string x, int y) -> float {
return y+9.3;
}
auto f( int x, int y) -> int
{
switch(x)
{
case 0: {
auto g = [=](auto...args) { return f(args..., y); };
std::cout << g("this string") << "\n";
return 0;
} break;
case 1: {
return y;
} break;
default:
return 7;
}
}
};
int main () {
mystruct h;
std::cout << h.f(1,4) << "\n";
std::cout << h.f(0,2) << "\n";
}
Maybe in reality there are more switch cases, and g needs to be hoisted above the switch statement?

Related

C++: How to make a container indexed by std::function?

For indexing I use std::unordered_map and std::map. Both of them throws compiling errors when using as follow:
std::unordered_map<std::function<bool(Ent*)>, int> var;
std::unordered_map fails due referencing deleted function
std::map fails due no < operator
The ideal solution for me would be to use a type of map, but if is a must to use another type of container, then it shouldn't be a problem
One way of having functions as container key is to wrap them into functor structure
#include <unordered_map>
#include <typeinfo>
struct FunctorSum {
int operator()(int x, int y) {
return x + y;
}
};
struct FunctorMult {
int operator()(int x, int y) {
return x * y;
}
};
int main() {
std::unordered_map<size_t, int> funcToInt;
funcToInt[typeid(FunctorSum).hash_code()] = 0;
funcToInt[typeid(FunctorMult).hash_code()] = 1;
return 0;
}
Here I used typeid as hash, but it can also be hardcoded into functor struct.
Another way is to use std::function::target_type to calculate hash of the function, which will work only with lambdas. But you can always wrap any function into lambda.
#include <iostream>
#include <functional>
using FuncType = std::function<bool(int)>;
bool x(int v) { return v == 0; }
std::string hash(FuncType f) {
return f.target_type().name();
}
int main() {
auto y = [](int v) { return v == 1; };
auto z = [](int v) { return v == 2; };
std::cout << "x: " << hash(x) << std::endl;
std::cout << "y: " << hash(y) << std::endl;
std::cout << "z: " << hash(z) << std::endl;
return 0;
}
Output
x: PFbiE
y: Z4mainEUliE_
z: Z4mainEUliE0_

Why is my lambda function not getting executed?

I have the following function and this is called by main. But I don't see the lambda function being executed.
int LambdaTest(int x, int y, bool bLambda) {
cout << "Lambda Rxd : " << bLambda << endl;
if (bLambda) {
return x + y;
} else {
return ((x > y) ? (x - y) : (y - x));
}
}
int main() {
int x = 10, y = 30;
int val = -1;
val = LambdaTest(x, y, [](int x) -> bool {
return x > 15;
});
cout << "Lambda test 1: " << val << endl;
val = LambdaTest(x, y, [](int y) -> bool {
return y > 15;
});
cout << "Lambda test 2: " << val << endl;
return 0;
}
In this main function my expectation is that the lambda function which is passed as third parameter of the function call shall execute and return true or false.
But I don't see the right value being passed to the function body.
Is there any extra need to be done?
You have stateless lambda.
Stateless lambda can be converted to pointer to function. So your lambdas are converted into void (*)(int), and this pointer is assigned to bool what gives always true.
To call lambda "in fly" you need to add () with parameter:
val = LambdaTest(x, y, [](int x) -> bool {
return x > 15;
}(x) ); // <---
cout << "Lambda test 1: " << val << endl;
val = LambdaTest(x, y, [](int y) -> bool {
return y > 15;
}(y) ); // <---
[](){} -> bool ( /*here passed arguments */ );
Another solution is to store functor generated by lambda expression in some variable and then apply () on that object:
auto l1 = [](int x) -> bool {
return x > 15;
};
val = LambdaTest(x, y, l1(x));
cout << "Lambda test 1: " << val << endl;

C++ -- How write a function, that return the derivative of a real valued function, not the value of the derivative

This function calculates the value of the Derivation of the Function Foo at X
double Deriv( double(* Foo)(double x), double X )
{
const double mtDx = 1.0e-6;
double x1 = Foo(X+mtDx);
double x0 = Foo(X);
return ( x1 - x0 ) / mtDx;
}
I would like to write a Funktion, which returned not the value of the derivation at X, but a new function which IS the derivation of the function Foo.
xxxx Deriv( double(* Foo)(double x) )
{
return Derivation of Foo;
}
Then it would be possible to write
SecondDeriv = Deriv( Deriv( Foo ))
Is it possible in C++ according to new standard to write such a function ?
I think with old standard it was impossible.
Once you can compute the value of a function at one point, you can use that to implement your general function. Lambda expressions allow you to generate those derived functions easily:
auto MakeDerivative(double (&f)(double)) {
return [=](double x) { return Deriv(f, x); };
}
If you want to be able to use stateful functions, you may need to update your Deriv to be a function template whose first parameter type is a template parameter. This is true in particular if you want to apply MakeDerivative repeatedly (since its return types are stateful closures):
template <typename F>
double Deriv(F f, double x) {
// your code here
}
template <typename F>
auto MakeDerivative(F f) {
return [=](double x) { return Deriv(f, x); };
}
However, you may be interested in techniques like "automatic differentiation" which allow you to express the derivative directly in terms of the definition of the original function, at the cost of working on an enlarged domain (an infinitesimal neighbourhood, essentially).
Here's one way to do it.
#include <iostream>
#include <functional>
std::function<double(double)> Deriv( double(*Foo)(double x) )
{
auto f = [Foo](double x) -> double
{
const double mtDx = 1.0e-6;
double x1 = Foo(x+mtDx);
double x0 = Foo(x);
return ( x1 - x0 ) / mtDx;
};
return f;
}
double Foo(double x)
{
return x*x;
}
double Bar(double x)
{
return x*x*x;
}
int main()
{
std::cout << Deriv(Foo)(10) << std::endl;
std::cout << Deriv(Bar)(10) << std::endl;
}
Output:
20
300
Using generic lambda, implementing a toy derivative is simple. In the following code, derivative is a derivative operator in the math sense. It accepts a function double -> double, produces its derivative double -> double.
#include <iostream>
double delta = 0.001;
auto derivative = [] ( auto foo ) {
return [foo] (double x) {
// the simplest formula for numeric derivative
return (foo(x + delta) - foo(x)) / delta;
};
};
// test
int main() {
auto quar = [] ( double x ) { return x * x; };
auto dev_quar = derivative(quar);
auto dev_dev_quar = derivative(dev_quar);
for ( double s = 0.0; s < 10.0; ++s ) {
std::cout << "(" << quar(s) << "," << dev_quar(s) << "," << dev_dev_quar(s) << ")\n";
}
}

C++ std::function variable with varying arguments

In my callback system I want to store std::function (or something else) with varying arguments.
Example:
I want to call void()
I want to call void(int, int)
I want 1) and 2) to be stored in the same variable and choose what to call in actuall call
FunctionPointer f0;
FunctionPointer f2;
f0();
f2(4, 5);
Is it possible to do something like this? Or I have to create several "FuntionPointer" templates based on input arguments count.
EDIT
Is it possible to utilize std::bind somehow for this task? With std::bind I can have std::function<void()> f = std::bind(test, 2, 5);
EDIT 2
Practical use case: I have a trigger system and I want to assign funtion pointers to actions, so when action happen, function is called.
Pseudo-code sample:
structure Trigger
{
Function f;
}
Init:
Trigger0.f = pointer to some function ()
Trigger1.f = pointer to some function (a, b)
Input:
Find Trigger by input
if (in == A) Trigger.f();
else Trigger.f(10, 20)
or if possible
Input:
Find Trigger by input
if (in == A) f = bind(Trigger.f);
else f = bind(Trigger.f, 10, 20);
f()
std::function<void()> and std::function<void(int, int)> are two absolutely distinct types. You need some sort of union functionality (or polymorphism) to store an object of an unknown type.
If you can use Boost, you could easily do this with boost::variant:
// Declaration:
boost::variant<std::function<void()>, std::function<void(int, int)> > f;
// Calling, explicit:
if (fContainsNullary()) {
boost::get<std::function<void()>>(f)();
} else {
boost::get<std::function<void(int, int)>>(f)(4, 5);
}
It is up to you to provide the logic of fContainsNullary(). Alternatively, you can use the variant's own stored knowledge of value type by using a visitor:
struct MyVisitor : boost::static_visitor<void>
{
result_type operator() (const std::function<void()> &a) {
a();
}
result_type operator() (const std::function<void(int, int)> &a) {
a(4, 5);
}
};
// Calling, via visitor:
boost::apply_visitor(MyVisitor(), f);
If Boost is not an option, you can hand-craft a suitable union for much the same purpose.
The following solution might work for you (I'm not sure that the code is absolutely correct here):
Create a wrapper for std::function with virtual destructor to enable using dynamic cast
class function_wrapper_base
{
virtual ~function_wrapper_base();
}
template <class... Args>
class function_wrapper
: public function_wrapper_base
{
public:
std::function<void, Args...> f;
...
};
Then create a class variant_function_holder
class variant_function_holder
{
std::unique_ptr<function_wrapper_base> f;
...
template <class... Args>
void operator()(Args&&... args)
{
function_wrapper<std::decay<Args>::type...> * g = dynamic_cast<function_wrapper<std::decay<Args>::type...>>(f.get());
if (g == nullptr)
{
// ToDo
}
g->f(std::forward<Args>(args)...);
}
};
Well, if you can use RTTI, you can define a MultiFuncObject like this, and you can easily bind other functions. Also, you can easily call them. But unfortunately, this approach only works for a limited number of arguments. But actually boost::bind also supports limited number of arguments (by default 9). So you can extend this class to satisfy your needs.
Before giving you the source of MultiFuncObject, I want to show you how you can use it. It takes an template argument to be used as return type. You can bind new functions with += operator. With some template magic, the class distinguishes differences between bound functions with same count of arguments with at least one different argument type.
You need C++11, because MultiFuncObject uses std::unordered_map and std::type_index.
Here is usage:
#include <iostream>
using namespace std;
void _1() {
cout << "_1" << endl;
}
void _2(char x) {
cout << "_2" << " " << x << endl;
}
void _3(int x) {
cout << "_3" << " " << x << endl;
}
void _4(double x) {
cout << "_4" << " " << x << endl;
}
void _5(int a, int b) {
cout << "_5" << " " << a << " " << b << endl;
}
void _6(char a, int b) {
cout << "_6" << " " << a << " " << b << endl;
}
void _7(int a, int b, int c) {
cout << "_7" << " " << a << " " << b << " " << c << endl;
}
int main() {
MultiFuncObject<void> funcs;
funcs += &_1;
funcs += &_2;
funcs += &_3;
funcs += &_4;
funcs += &_5;
funcs += &_6;
funcs += &_7;
funcs();
funcs('a');
funcs(56);
funcs(5.5);
funcs(2, 5);
funcs('q', 6);
funcs(1, 2, 3);
return 0;
}
I hope this is close to what you want. Here is the source of MultiFuncObject:
#include <typeinfo>
#include <typeindex>
#include <unordered_map>
using namespace std;
template <typename R>
class MultiFuncObject {
unordered_map<type_index, void (*)()> m_funcs;
public:
MultiFuncObject<R> operator +=( R (* f)() ) {
m_funcs[typeid( R() )] = (void (*)()) f;
return *this;
}
template <typename A1>
MultiFuncObject<R> operator +=( R (* f)(A1) ) {
m_funcs[typeid( R(A1) )] = (void (*)()) f;
return *this;
}
template <typename A1, typename A2>
MultiFuncObject<R> operator +=( R (* f)(A1, A2) ) {
m_funcs[typeid( R(A1, A2) )] = (void (*)()) f;
return *this;
}
template <typename A1, typename A2, typename A3>
MultiFuncObject<R> operator +=( R (* f)(A1, A2, A3) ) {
m_funcs[typeid( R(A1, A2, A3) )] = (void (*)()) f;
return *this;
}
R operator()() const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R() ));
if (it != m_funcs.end()) {
R (*f)() = ( R (*)() )(it->second);
(*f)();
}
}
template <typename A1>
R operator()(A1 a1) const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R(A1) ));
if (it != m_funcs.end()) {
R (*f)(A1) = ( R (*)(A1) )(it->second);
(*f)(a1);
}
}
template <typename A1, typename A2>
R operator()(A1 a1, A2 a2) const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R(A1, A2) ));
if (it != m_funcs.end()) {
R (*f)(A1, A2) = ( R (*)(A1, A2) )(it->second);
(*f)(a1, a2);
}
}
template <typename A1, typename A2, typename A3>
R operator()(A1 a1, A2 a2, A3 a3) const
{
unordered_map<type_index, void (*)()>::const_iterator it = m_funcs.find(typeid( R(A1, A2, A3) ));
if (it != m_funcs.end()) {
R (*f)(A1, A2, A3) = ( R (*)(A1, A2, A3) )(it->second);
(*f)(a1, a2, a3);
}
}
};
It stores different function prototypes using std::unordered_map with keys of std::type_index and values of void (*)(). When needed, the correct function is retrieved using that map.
Here is the working example
C++11 to the rescue!
If you can generalize your function to a functor object taking no arguments, then you can call it with any lambda.
#include <iostream>
using namespace std;
template <class F>
void call_it(F&& f)
{
f();
}
int main()
{
int x = 50, y = 75;
call_it([] () { cout << "Hello!\n"; });
call_it([x,y] () { cout << x << " + " << y << " = " << x + y << '\n';});
return 0;
}
If std::function is not necessary for you, you can create a proxy class.
class fn_t {
public:
typedef void (*fn_1_t)();
typedef void (*fn_2_t)(int, int);
fn_1_t fn_1;
fn_2_t fn_2;
fn_t operator=(fn_1_t func_1) { fn_1 = func_1; return *this; }
fn_t operator=(fn_2_t func_2) { fn_2 = func_2; return *this; }
void operator()() { (*fn_1)(); }
void operator()(int a, int b) { (*fn_2)(a, b); }
};
#include <iostream>
using namespace std;
void first() {
cout << "first" << endl;
}
void second(int a, int b) {
cout << "second " << a << " : " << b << endl;
}
int main() {
fn_t f;
f = &first;
f = &second;
f();
f(5, 4);
return 0;
}
Class fn_t automatically works with two prototypes you want, assigns automatically needed one, and it can call functions with both prototypes by overlading () operator with appropriate parameters.
You may want to check for validity of function pointers fn_1 and fn_2 but I didn't include this checking for minimality.
The advantage of this is that you only need C++ and not even STL and Boost.
The other answers are fine but I want to show my solution as well.
It's a small header with which you can "elongate" function signatures.
This allows you to do this (extract from the github example):
int foo_1p(int a);
int foo_2p(int a, int b);
int foo_3p(int a, int b, int c);
int foo_4p(int a, int b, int c, int d);
int foo_5p(int a, int b, int c, int d, int e);
int foo_6p(int a, int b, int c, int d, int e, int f);
int foo_7p(int a, int b, int c, int d, int e, int f, std::string g);
...
int main()
{
std::unordered_map<std::string, std::function<int(int, int, int, int, int, int, std::string)>> map;
map["foo_1p"] = ex::bind(foo_1p, ph, ph, ph, ph, ph, ph);
map["foo_2p"] = ex::bind(foo_2p, ph, ph, ph, ph, ph);
map["foo_3p"] = ex::bind(foo_3p, ph, ph, ph, ph);
map["foo_4p"] = ex::bind(foo_4p, ph, ph, ph);
map["foo_5p"] = ex::bind(foo_5p, ph, ph);
map["foo_6p"] = ex::bind(foo_6p, ph);
map["foo_7p"] = foo_7p;
for (const auto& f : map)
{
std::cout << f.first << " = " << f.second(1, 1, 1, 1, 1, 1, "101") << std::endl;
}
}

Lambda functions as class members

Is it possible to accept two different types of lambda function as class members without knowing their template arguments ahead of time?
struct two_functors {
std::function<???> a;
std::function<???> b;
...
};
Such that something like this would be possible:
void main(){
vector<two_functors> many_functors;
int a = 2;
int b = 3;
double c = 4.7;
double d = 8.4;
two_functors add_and_subtract;
add_and_subtract.a = [a, b](int x, int y){cout << x + y << endl;};
add_and_subtract.b = [c, d](double x, double y){cout << x - y << endl;};
two_functors multiply_and_divide;
multiply_and_divide.a = [c, d](double x, double y){cout << x * y << endl;};
multiply_and_divide.b = [a, b](int x, int y){cout << x / y << endl;};
many_functors.push_back(add_and_subtract);
many_functors.push_back(multiply_and_divide);
for (auto functors : many_functors){
functors.a();
functors.b();
}
}
If you just want to construct two_functors at various times, but execute them later in sequence all at once, you could just use the captured data.
struct two_functors
{
function<void ()> a;
function<void ()> b;
};
int main()
{
vector<two_functors> many_functors;
int a = 2;
int b = 3;
double c = 4.7;
double d = 8.4;
two_functors add_and_subtract {
[a, b](){cout << a + b << endl;},
[c, d](){cout << c - d << endl;}
};
two_functors multiply_and_divide {
[c, d](){cout << c * d << endl;},
[a, b](){cout << a / b << endl;}
};
many_functors.push_back(add_and_subtract);
many_functors.push_back(multiply_and_divide);
for (auto functors : many_functors){
functors.a();
functors.b();
}
}
That's essentially a tuple. You can see how the interface is implemented for that.
template< class F0, class F1 >
struct two_functors {
F0 func0;
F1 func1;
};
template< class F0, class F1 >
two_functors<F0, F1> make_two_functor( F0&& f0, F1&& f1 )
{
// Added [std::forward][2]
return two_functors<F0,F1>( std::forward<F0>(f0), std::forward<F1>(f1) );
}
Not an attempt to answer (I just need the formatting feat), just a variation of Steven's proposal
template<typename A, typename B>
two_functors<A,B> make_two_functors(A&& a, B&& b) {
return two_functors<A,B> {a, b};
}
Does that have any downside compared to using std::forward<T>?
Btw - I somehow wish the need for such "makers" would have vanished with C++11.
An alternative to Steven's answer would be to use an intermediate "umbrella" class.
EDIT: Just compiled an example on g++ (GCC) 4.5.3
#include <functional>
#include <iostream>
using namespace std;
class myfunction
{
};
template <typename T>
class specificFunction : public myfunction
{
public:
function<T> f;
specificFunction(function<T> pf)
{
f = pf;
}
};
struct two_functors {
myfunction* a;
myfunction* b;
};
int main()
{
myfunction* f = new specificFunction<void(int,int)> ([](int a, int b) { cout << a << " - " << b << endl; });
myfunction* f2 = new specificFunction<void(double,int)> ([](double a, int b) { cout << a << " - " << b << endl; });
two_functors tf;
tf.a = f;
tf.b = f2;
((specificFunction<void(int,int)>*)(tf.a))->f(4,5);
((specificFunction<void(double,int)>*)(tf.b))->f(4.02,5);
}