I have two classes, ClassA and ClassB.
ClassA has three methods:
double Foo(double, ClassB);
double Bar(double (*f)(double));
double Baz(double, ClassB);
I would like to define a function Qux inside Foo, based on Baz but without the argument of type ClassB: i.e. of the kind "double Qux(double)" so that I can pass it to Bar:
double ClassA::Foo(double x, ClassB y)
{
// double Qux(double .) = Baz(., y)
Bar((*Qux))
}
Does some one have any idea?
I guess some will answer this is not the good way to do it. So just to explain the concrete situation, I am pricing financial assets using a numerical method (http://en.wikipedia.org/wiki/Simpson%27s_rule) in order to compute integrals:
ClassA: FinancialAsset
ClassB: PrincingModel
Foo: FinancialAsset.Price(date, PrincingModel)
Bar: FinancialAsset.SimpsonMethod(FunctionOneArgument)
Baz: FinancialAsset.FunctionTwoArguments(date, PrincingModel)
And I am looking for:
Qux: FunctionOneArgument(date) = FinancialAsset.FunctionTwoArguments(date, PrincingModel)
I am not sure what is the good way to address this structure. I you have a better / more c++'s way to do it, I'll take :)
Thanks
You can't do that exactly, because your Bar function is taking a pointer to a regular function, but you can use this instead:
class A {
...
public:
double Foo(double, ClassB);
double Bar(std::function<double(double)> f);
double Baz(double, ClassB);
};
double ClassA::Foo(double x, ClassB y)
{
auto Qux = [&](double x) { Baz(x,y); };
return Bar(Qux);
}
std::function is a more general way of representing function-like objects. You can convert a regular function, a lambda, or a function object to it.
Depending on whether you have C++11 or not, you either want std::bind and std::function or boost::bind and boost::function for older C++ versions.
binding allows you to take a function and bind 0 or more of the parameters, or rearrange the parameters. Indeed something you have above would look like this:
double ClassA::Foo(double x, ClassB y)
{
boost::function<double> baz = boost::bind(this, ClassA::Baz, _1, y);
Bar(baz);
}
And Bar's signature would take a boost::function instead of a function pointer.
Note my syntax might be slightly off for binding memeber functions, have a look at the documentation for details.
see here:
http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html
Or here: http://en.cppreference.com/w/cpp/utility/functional/bind
You can do it without changing any function signatures (and C++11 or boost), but I wouldn't suggest it if you can avoid it. It's ugly, not thread-safe, and in general not very nice:
#include <iostream>
struct B
{
// some data in B
int i;
};
struct A
{
//some data in A
double d;
// the functions you defined in A
double Foo(double x, B y);
double Bar(double (*f)(double));
double Baz(double x, B y);
};
// a poor substitutes for closures
struct
{
A *a;
B *b;
} hack;
double Qux(double x2)
{
// use the stored pointer to call Baz on x2
return hack.a->Baz(x2, *hack.b);
}
double A::Foo(double x, B y)
{
// store pointers for use in Qux
hack.a = this;
hack.b = &y;
// do something with x
d += x;
double result = Bar(&Qux);
return result;
}
double A::Bar(double (*f)(double))
{
// do something with d, call the passed function
d += 1;
return f(d);
}
double A::Baz(double x, B y)
{
// do something with the passed data
return x + y.i;
}
int main()
{
A a;
a.d = 1.25;
B b;
b.i = 2;
std::cout << a.Foo(.25, b) << std::endl; // should be 4.5
return 0;
}
Related
There are other questions regarding how to pass an external function as an argument to a function in C++, but I am struggling to apply those answers to the case where the target function is the constructor function for a novel class.
Here is what I am trying to do:
#include <iostream>
double external_function(double x, double y) {
return x * y;
}
class foo {
public:
// Initialize a function (?) as a method of class foo
double func(double, double);
// Construct an instance of the class by supplying a pointer to an external function
foo(double(*func_in)(double, double)) {
func = *func_in;
}
// When calling this method, evaluate the external function
double eval(double x, double y) {
return func(x, y);
}
};
int main() {
foo foo_instance(&external_function);
std::cout << foo_instance.eval(1.5, 2); // Should print 3
return 0;
}
I would like to have func as a method of the foo class because I later will write methods of foo that do other things with func, e.g. search for a local minimum.
By analogy, here is working code that passes an external constant instead of a function:
#include <iostream>
double external_value = 1.234;
class bar {
public:
// Initialize a value as a method of class bar
double val;
// Construct an instance of the class by supplying a pointer to an external value
bar(double* val_in) {
val = *val_in;
}
// When calling this method, return the external function
double eval() {
return val;
}
};
int main() {
bar bar_instance(&external_value);
std::cout << bar_instance.eval(); // 1.234
return 0;
}
Like this
class foo {
public:
// Initialize a function pointer as a method of class foo
double (*func)(double, double);
// Construct an instance of the class by supplying a pointer to an external function
foo(double(*func_in)(double, double)) {
func = func_in;
}
// When calling this method, evaluate the external function
double eval(double x, double y) {
return func(x, y);
}
};
In your version func was an undefined method of the class not the function pointer you wanted it to be.
Here is the example using std::function:
#include <functional>
class foo {
public:
// Initialize a function as a method of class foo
std::function<double(double, double)> func;
// Construct an instance of the class by supplying a pointer to an external function
foo(std::function<double(double, double)> func_in) {
func = func_in;
}
// When calling this method, evaluate the external function
double eval(double x, double y) {
return func(x, y);
}
};
STRUGGLING WITH C++ CONSTRUCTOR ARGUMENTS
So, I've just came from TS/JS/Py and trying to understand C++ concepts. But I'm struggling with using the parameter of constructor of the class FOR declaring default value for an argument. Here is the code I'm trying to run:
double Phythagorean_Hypotenuse (int& a, int& b ) {
return sqrt((a * a) + (b * b));
};
class Triangle {
public:
int a;
int b;
double c;
Triangle(int a_param, int b_param, double c_param = Phythagorean_Hypotenuse(a_param, b_param)) {
a = a_param;
b = b_param;
c = c_param;
}
};
and inside of the main function
Triangle mytri_1(10, 20);
std::cout << mytri_1.a << std:endl;
But when I try to run this code, IDE is throwing me some errors like
[Error] 'a_param' was not declared in this scope
or
[Error] call to 'Triangle::Triangle(int, int, double)' uses the default argument for parameter 3, which is not yet defined
So, please, can someone who can fix this answer the question?
Thanks.
There are some issues that prevent your code from compiling, namely:
Constructors do not have return type.
double c_param = Phythagorean_Hypotenuse(a_param, b_param) is not valid for a parameter, a_param, b_param will not be recognized.
Recommend change:
Since the result of a hypothenuse calculation will most likely be a decimal value, c should be a double.
You can do something like this:
Running sample
#include <iostream>
#include <cmath>
double Phythagorean_Hypotenuse (int& a, int& b ) {
return sqrt((a * a) + (b * b));
};
class Triangle {
public:
int a;
int b;
double c; //should be double
//initializer list is a good practice for member initialization
Triangle(int a_param, int b_param)
: a(a_param), b(b_param), c(Phythagorean_Hypotenuse(a, b)) {}
};
int main(){
Triangle mytri_1(10, 20);
std::cout << mytri_1.a << std::endl;
std::cout << mytri_1.b << std::endl;
std::cout << mytri_1.c << std::endl;
}
Output:
10
20
22.3607
As the compiler is pointing out, the other constructor arguments are not available as default parameters for the c_param argument. Rather than using default values, just overload the constructor, including one that just accepts 2 parameters. This constructor can then invoke the other constructor that accepts all 3:
// Constructor overload that accepts all 3 parameters
Triangle(int a_param, int b_param, double c_param):
a(a_param), b(b_param), c(c_param) {
}
// Constructor overload that accepts just a and b, call the other constructor
// to set all 3 members
Triangle(int a_param, int b_param):
Triangle(a_param, b_param, Phythagorean_Hypotenuse(a_param, b_param)) {
}
Default parameter values cannot reference other parameters. You can define two overloads, one of which delegates to the other, to do what you want:
class Triangle {
public:
double a;
double b;
double c;
Triangle(double a_param, double b_param, double c_param)
: a{a_param},
b{b_param},
c{c_param}
{}
Triangle(double a_param, double b_param)
: Triangle{a_param, b_param, Phythagorean_Hypotenuse(a_param, b_param)}
{}
};
Live Demo
A few other notes:
Class constructors do not have a return type. I changed void Triangle(...) to Triangle(...)
I used constructor initialization lists instead of assignment in the constructor's body. There's likely no difference for small primitive values like ints or doubles, but it's a good habit to get into and can make a big difference for more complex types
int doesn't make sense for the type of c (or a or b for that matter). The sides of a triangle are unlikely to all be integers
There's no reason to pass parameters to Pythagorean_Hypotenuse by reference. It's simpler and likely faster to pass them by value
Are there any methods in C++ I can use, such as overloading or templating, that would allow me to pass class instances as an argument to a cmath function? For example, if I had a class named “Point” (shown below), is there any way that I could perform the operation std::abs(Point(-4, -9)) and have it return Point(4, 9)?
#include <iostream>
#include <cmath>
class Point{
private:
double x, y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
// Approach 1 that I would like to avoid
static Point abs1(const Point &p1) {
return Point(std::abs(p1.x), std::abs(p1.y));
}
// Approach 2 that I would like to avoid
Point abs2(void) {
return Point(std::abs(x), std::abs(y));
}
};
int main()
{
Point pt1(-4.0, -9.0), pt2;
pt2 = std::abs(pt1) // <-- What I would like to be able to do
pt2 = Point::abs1(point_d); // <-- Function call 1 that I would like to avoid
pt2 = point_d.abs2(); // <-- Function call 2 that I would like to avoid
return 0;
}
Or am I restricted to using class based methods that would require me calling Point::abs(Point(-4, -9)) or Point(-4, -9).abs()? So in short, can I augment the cmath function in anyway to accept a class instance?
I have had a look around and I can’t find any information on the subject, however I am quite new to C++. So, I would appreciate any information on how this might be done, if it can be done, and whether such an action is ill-advised, and if so, why?
Thanks in advance.
You would do it like this.
#include <iostream>
#include <cmath>
class Point{
double x, y;
public:
Point(double x, double y)
: x(x), y(y)
{
}
friend Point abs(const Point &p1) {
return Point(std::abs(p1.x), std::abs(p1.y));
}
};
int main()
{
using std::abs;
Point pt1(-4.0, -9.0);
double x = 5.5;
// this will work even if Point is in its own namespace
// because of ADL
Point pt2 = abs(pt1);
// this works because for this function, we have pulled
// std::abs into the global namespace
double y = abs(x);
return 0;
}
Have a look at this reference page:
For calculating absolute values, in cmath you just have a bunch of overloads that operate on primitive types:
int abs(int j);
long int abs(long int j);
long long int abs(long long int j);
float abs(float j);
double abs(double j);
long double abs(long double j);
Since these functions are not templated, there is no way you can pass to them a Point class and get back another instance of Point. They can only receive a primitive type, and return the same type.
Something like this (similar in terms of syntax only) could only happen, if your Point class was convertible to one of these primitive types. E.g. in the following snippet, I defined class A, which is implicitly convertible to and from int, therefore when I call abs with an instance of A, it is automatically converted to int, passed to the appropriate overload of abs, and finally the result is converted back to A.
#include <cmath>
#include <iostream>
class A
{
public:
A(int x_) // implicit conversion from int
: x(x_)
{}
operator int()
{
return x; // implicit conversion to int
}
private:
int x;
};
int Foo(int x)
{
return x * 2;
}
int main()
{
A a1(-2);
A a2 = Foo(a1);
A a3 = std::abs(a1);
std::cout << "a2: " << a2 << "\n";
std::cout << "a3: " << a3 << "\n";
getchar();
}
But this is pretty much how far you can go with this trick, which I think doesn't cover what you want. I believe the best approach in your case is to create some utility function, that does what you want. I would rather go for a free function, instead of a static member, to not litter the class with unnecessary utility methods, i.e. something like this
namespace PointUtils
{
Point abs(const Point& p);
}
The two approaches you show are valid ways to do it. There is no way to use std::abs directly on your Point class.
Another way is to make your static abs1 function into a free abs function. If it's declaration is in a header file, it essentially overloads the std::abs function. In order to implement that as a free function, you would need to implement member functions to get x and y or make your free function a friend of you Point class.
There is this C code:
*(*(A+i)+j) = aaa(*bbb,0,PI)/(16*PI);
aaa is a function, and bbb is another function:
double bbb(double x, double y)
{
int i,j,k,l,m,n;
*(K+1)=sin(x)*cos(y);
*(K+2)=sin(x)*sin(y);
*(K+3)=cos(x);
...
...
My question is, when bbb is called inside the function aaa, there isn't any parentheses following bbb, that is, no variable is passed into function bbb. So what are the values of x and y in the function bbb? Both zero?
Alright, this is part of a really long code:
*(*(A+i)+j) = aaa(*bbb,0,PI)/(16*PI);
aaa and related functions:
double aaa(double (*func)(double, double), double x1, double x2)
{
double qgaus(double (*func)(double), double a, double b);
double f1(double x);
nrfunc=func;
return qgaus(f1,x1,x2);
}
double f1(double x)
{
double qgaus(double (*func)(double), double a, double b);
double f2(double y);
double yy1(double),yy2(double);
xsav=x;
return qgaus(f2,yy1(x),yy2(x));
}
double f2(double y)
{
return (*nrfunc)(xsav,y);
The capital variable K in function bbb is a global variable defined in main().
I just want to know what are the x and y values passed into function bbb.
Most probably (assuming the code compiles) aaa is a function that takes as its first parameter a pointer-to-function. It doesn't matter if you dereference the pointer-to-function, the call is still valid. So in your case *b is simply decaying to a function pointer, which presumably is used inside aaa (of which definition you don't provide). Simple example:
#include <iostream>
void f(int x)
{
std::cout << "void f(int) invoked, with x = " << x << std::endl;
}
void a(void (*fptr)(int), int x)
{
fptr(x); // call the function pointed by fptr with argument x
}
int main()
{
a(f, 10);
a(*f, 20); // same as above
a(****f, 42); // still the same
}
So in your code you first pass the pointer to function, then the arguments of the function, which are then used when calling the latter via the pointer-to-function.
This question already has answers here:
How do you pass a member function pointer?
(6 answers)
Closed 9 years ago.
I have a class
class A{
A(/*constructor arguments*/);
double MethA(double);
};
And I want to pass the method MethA in a function that takes a pointer to a function :
double function(double (*f)(double), double x){
return f(x);
}
So what I'm doing is to call
A a(/*constructor arguments*/);
function(a.MethA,1.0);
but it doesn't compile.
I'm pretty sure that this question is answered somewhere else, but I couldn't find where because I'm not sure that the terminology I use is correct. Am I trying to pass a pointer on a class method as a function argument ? Or, to pass a function pointer as a member of a class... I'm confused :-(
When you need to use a pointer to member function, you need to pass two separate things:
what member function to call and
what instance to call it on.
In C++, you can't combine them in one construct, like you want to:
A a;
bar(a.foo);
is not valid C++.
Instead, you have to do this:
A a;
bar(a, &A::foo)
And declare and implement bar() accordingly:
void bar(A &a, void (A::*method)()) {
a.*method();
}
See Arkadiy's answer if you want to see how to properly use member function pointers.
BUT
As requested in the comments: if the compiler you are using supports lambdas (some without full C++11 do). You can do something like the following, which looks more like the syntax you are attempting to use.
Your definition for function changes to something like:
template <typename F>
double function(F f, double x){
return f(x);
};
a function template that accepts a parameter that is callable with a double.
At your call-site you do this:
A a(/*constructor arguments*/);
function([&](double x){return a.MethA(x);},1.0);
That generates a function object in-place that is bound to your class instance a by reference.
The template can be made fully typesafe with some magic in <type_traits>, but as-is it will give you template spew if you pass something very wrong.
It has to be a static function!
#include <iostream>
#include <cassert>
class A {
public:
static double MethA(double x) { return 5 * x; }
};
typedef double (*ftype)(double);
double function(ftype f) {
assert(f != NULL);
return f(7);
}
int main(int, char**) {
// expect "35\n" on stdout
std::cout << function(A::MethA) << "\n";
}
It has to be static because you can't access any of A's variables without knowing which A object are you refering to! If you need A's non-static member variables, you need to pass a reference to an a into the static function:
#include <iostream>
#include <cassert>
class A {
double fX;
public:
A(double x) : fX(x) { }
double methB(double x) const { return fX * x; }
static double MethB(double x, const A& a) {
return a.methB(x);
}
};
typedef double (*ftype2)(double, const A&);
double function_with_context(ftype2 f, const A& a) {
assert(f != NULL);
return f(7, a);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function_with_context(A::MethB, a) << "\n";
}
But it's sometimes better to use inheritance and polymorphism to achieve this sort of interface:
#include <iostream>
class MyInterface {
public:
virtual double f(double x) const = 0;
};
class A : public MyInterface {
double fX;
public:
A(double x) : fX(x) { }
double f(double x) const {
return fX * x;
}
};
double function(const MyInterface& o) {
return o.f(7);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function(a) << "\n";
}