Jul 12, 2013 at 2:42pm UTC
Hi,
I can't figure out how to solve this problem:
I would like to have a function f(x) that depends of a parameter p, so it's f(x;p); the problem is that I need a function with exately one argument x.
For example I can't use
int f(int x, int p)
the prototype of the function must be like
int f(int x)
I was thinking to use a function that return a function pointer but I still don't know how to insert the parameter p.
Thank you!
Jul 12, 2013 at 5:51pm UTC
in this case &d.f is a pointer to a function int(int), is it right?
Almost. The address of member functions is obtained writing &classname::funcname (&dummy::f).
dummy::f() is a function that takes two arguments: dummy* this, int x.
When you call a member function the first parameter is automatically passed (it's the object calling the function).
If you want to assign dummy::f() to a function pointer it should be declared as
int (*pointer)(dummy*, int )
Last edited on Jul 12, 2013 at 5:54pm UTC
Jul 12, 2013 at 9:34pm UTC
Something like this? (the code below)
If so, then maybe std::bind (or tr1::bind, if your using a pre-C++11 compiler) could help out? (see following post...)
Andy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
#include <iostream>
using namespace std;
namespace example {
double divide_by(double lhs, double rhs) {
return lhs / rhs;
}
double minus(double lhs, double rhs) {
return lhs - rhs;
}
} // end namespace example
typedef double (* func_2_param)(double lhs, double rhs);
class currier_1 {
private :
func_2_param m_func;
double m_lhs;
public :
currier_1(func_2_param func, double lhs)
: m_func(func), m_lhs(lhs) {}
double operator ()(double rhs) {
return (*m_func)(m_lhs, rhs);
}
};
template <func_2_param func>
class currier_2 {
private :
double m_lhs;
public :
currier_2(double lhs) : m_lhs(lhs) {}
double operator ()(double rhs) {
return (*func)(m_lhs, rhs);
}
};
void test1() {
cout << "test1\n\n" ;
double lhs = 3.0;
double rhs = 5.0;
currier_1 divide_by_5(example::divide_by, lhs);
currier_1 minus_5(example::minus, lhs);
double result_divide_by = divide_by_5(rhs);
double result_minus = minus_5(rhs);
cout << lhs << " / " << rhs << " = " << result_divide_by << endl;
cout << lhs << " - " << rhs << " = " << result_minus << endl;
cout << "\n" ;
}
void test2() {
cout << "test2\n\n" ;
double lhs = 7.0;
double rhs = 13.0;
currier_2<example::divide_by> divide_by_5(lhs);
currier_2<example::minus> minus_5(lhs);
double result_divide_by = divide_by_5(rhs);
double result_minus = minus_5(rhs);
cout << lhs << " / " << rhs << " = " << result_divide_by << endl;
cout << lhs << " - " << rhs << " = " << result_minus << endl;
cout << "\n" ;
}
int main() {
test1();
test2();
return 0;
}
test1
3 / 5 = 0.6
3 - 5 = -2
test2
7 / 13 = 0.538462
7 - 13 = -6
Last edited on Jul 12, 2013 at 11:29pm UTC
Jul 12, 2013 at 9:38pm UTC
The std::bind solution.
With tr1::bind, etc and without the auto declaration, it also runs on Visual C++ 2008.
This version was tested with Visual C++ 2010 and MinGW GCC 4.7.2 (with -std=c++11). I did not try to extend it to use a variadic template.
Andy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
using namespace std::placeholders;
typedef double (* func_1_param)(double x);
typedef double (* func_2_param)(double x, double y);
namespace example {
double divide_by(double lhs, double rhs) {
return lhs / rhs;
}
double minus(double lhs, double rhs) {
return lhs - rhs;
}
} // end namespace example
void test1() {
cout << "test1\n\n" ;
double lhs = 3.0;
double rhs = 5.0;
auto divide_by_5 = std::bind(example::divide_by, _1, rhs);
auto minus_5 = std::bind(example::minus, _1, rhs);
auto result_divide_by = divide_by_5(lhs);
auto result_minus = minus_5(lhs);
cout << lhs << " / " << rhs << " = " << result_divide_by << endl;
cout << lhs << " - " << rhs << " = " << result_minus << endl;
cout << "\n" ;
}
template <func_2_param func>
std::function<double (double )> currier_2_to_1(double y) {
return std::bind(func, y, _1);
}
void test2() {
cout << "test2\n\n" ;
double lhs = 5.0;
double rhs = 11.0;
auto result_divide_by = currier_2_to_1<example::divide_by>(lhs)(rhs);
auto result_minus = currier_2_to_1<example::minus>(lhs)(rhs);
cout << lhs << " / " << rhs << " = " << result_divide_by << endl;
cout << lhs << " - " << rhs << " = " << result_minus << endl;
cout << "\n" ;
}
typedef std::function<double (double )> func_2_param_to_1;
template <func_2_param func>
func_2_param_to_1 currier_2_to_1_w(double y) {
return std::bind(func, y, _1);
}
const double g_lhs = 7.0;
auto func_divide_by_lhs = currier_2_to_1_w<example::divide_by>(g_lhs);
auto func_minus_lhs = currier_2_to_1_w<example::minus>(g_lhs);
void test3() {
cout << "test3\n\n" ;
double rhs = 13.0;
auto result_divide_by = func_divide_by_lhs(rhs);
auto result_minus = func_minus_lhs(rhs);
cout << g_lhs << " / " << rhs << " = " << result_divide_by << endl;
cout << g_lhs << " - " << rhs << " = " << result_minus << endl;
cout << "\n" ;
}
func_2_param_to_1 curry_divide_by(double lhs) {
return currier_2_to_1_w<example::divide_by>(lhs);
}
func_2_param_to_1 curry_minus(double lhs) {
return currier_2_to_1_w<example::minus>(lhs);
}
void test4() {
cout << "test4\n\n" ;
double lhs = 11.0;
double rhs = 17.0;
auto curried_divide_by = curry_divide_by(lhs);
auto curried_minus = curry_minus(lhs);
auto result_divide_by = curried_divide_by(rhs);
auto result_minus = curried_minus(rhs);
cout << lhs << " / " << rhs << " = " << result_divide_by << endl;
cout << lhs << " - " << rhs << " = " << result_minus << endl;
cout << "\n" ;
}
template <func_2_param func>
func_2_param_to_1 curry_(double lhs) {
return currier_2_to_1_w<func>(lhs);
}
void test5() {
cout << "test5\n\n" ;
double lhs = 13.0;
double rhs = 19.0;
auto curried_divide_by = curry_<example::divide_by>(lhs);
auto curried_minus = curry_<example::minus>(lhs);
auto result_divide_by = curried_divide_by(rhs);
auto result_minus = curried_minus(rhs);
cout << lhs << " / " << rhs << " = " << result_divide_by << endl;
cout << lhs << " - " << rhs << " = " << result_minus << endl;
cout << "\n" ;
}
int main() {
test1();
test2();
test3();
test4();
test5();
return 0;
}
test1
3 / 5 = 0.6
3 - 5 = -2
test2
5 / 11 = 0.454545
5 - 11 = -6
test3
7 / 13 = 0.538462
7 - 13 = -6
test4
11 / 17 = 0.647059
11 - 17 = -6
test5
13 / 19 = 0.684211
13 - 19 = -6
Last edited on Jul 12, 2013 at 11:30pm UTC
Jul 13, 2013 at 11:00am UTC
It's defining a function pointer type (see below.)
You can also declare the function pointer variable without the typedef, but I find that a bit too confusing. e.g. this declares a function pointer variable
func which points at a function of the form
double funcname(double, double) , and initializes it to point at the function
divide_by .
double (* func)(double lhs, double rhs) = divide_by;
Andy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include <iostream>
using namespace std;
double divide_by(double lhs, double rhs) {
return lhs / rhs;
}
// typdef for function pointer to function of the form double funcname(double, double)
typedef double (* func_2_param)(double lhs, double rhs);
int main() {
// point function pointer at divide_by function
func_2_param func = divide_by;
float lhs = 3.0f;
float rhs = 4.0f;
// call function though pointer
double result = func(lhs, rhs);
cout << lhs << " / " << rhs << " = " << result << "\n" ;
return 0;
}
Last edited on Jul 14, 2013 at 1:53pm UTC
Jul 14, 2013 at 9:59am UTC
Thank you andy, very helpful!