C++ Passing a function to a function using functors - c++

I have two functors:
class SFunctor {
public:
SFunctor(double a) { _a = a; }
double operator() (double t) { return _a * sin(t); }
private:
double _a;
};
class CFunctor {
public:
CFunctor(double b) { _b = b; }
double operator() (double t) { return _b * cos(t); }
private:
double _b;
};
I want to pass one or the other of these functions to another function:
double squarer(double x, ??______?? func) {
double y = func(x);
return y * y;
}
In my main program I want to make a call like this:
CFunctor sine(2.);
SFunctor cosine(4.);
double x= 0.5;
double s = squarer(x, sine);
double c = squarer(x, cosine);
How do I specify the function fund, that is what goes in front of it in place of ??_?? ?

You can simply do it with templates
template <class F>
double squarer(double x, F& func) {
double y = func(x);
return y * y;
}

I'm not knocking on the above template answer. In fact, it may be the better choice of the two, but I wanted to point out that this can be done with polymorphism as well. For example...
#include <math.h>
#include <iostream>
using std::cout;
using std::endl;
class BaseFunctor {
public:
virtual double operator() (double t) = 0;
protected:
BaseFunc() {}
};
class SFunctor : public BaseFunctor {
public:
SFunctor(double a) { _a = a; }
double operator() (double t) { return _a * sin(t); }
private:
double _a;
};
class CFunctor : public BaseFunctor {
public:
CFunctor(double b) { _b = b; }
double operator() (double t) { return _b * cos(t); }
private:
double _b;
};
double squarer(double x, BaseFunctor& func) {
double y = func(x);
return y * y;
}
int main() {
SFunctor sine(.2);
CFunctor cosine(.4);
double x = .5;
cout << squarer(x,sine) << endl;
cout << squarer(x,cosine) << endl;
}
I ensured that this was a full working demo, so you can just copy it to test it. You will indeed observe two different numbers print to the terminal, thus proving that polymorphism can be used with functors. Again, I'm not saying this is better than the template answer, I just wanted to point out that it isn't the only answer. Even though the question has been answered, I hope this helps inform anyone who wants to be informed.

Related

Calling class constructor inside another class using a pointer to a member function

I am trying to initialize an object of a class inside a member function of another class. The problem is that I need to pass a function pointer to the constructor. I do not know how I can make this. This is the error:
no matching function for call to ‘inheritance01::inheritance01(double (inheritance02::*&)(double))’
inheritance01 LT (func);
The code below shows the problem.
class Base01 {
public:
Base01(double (*)(double));
virtual double calc(double) = 0;
double (*ptr_fd() const)(double) { return ptr_fd_; }
private:
double (*ptr_fd_)(double);
};
Base01::Base01(double (*f)(double))
: ptr_fd_(f)
{
}
//----------------------------------------------------
class inheritance01 : public Base01 {
public:
inheritance01(double (*ptr_f)(double));
virtual double calc(double);
};
inheritance01::inheritance01(double (*pf)(double))
: Base01(pf)
{
}
double inheritance01::calc(double t) { return 2.0 * t; }
//###################################################
class Base02 {
public:
Base02(double);
virtual double solution(double, double) = 0;
double a() { return a_; };
private:
const double a_;
};
Base02::Base02(double aa)
: a_(aa)
{
}
//------------------------------------------------------
class inheritance02 : public Base02 {
public:
inheritance02(double, double);
virtual double solution(double, double);
//static double sol_aux (double);
private:
double sol_aux(double);
const double b;
//double (inheritance02::*fptrsol_aux)(double u) = &inheritance02::sol_aux;
typedef double (inheritance02::*fptr)(double u);
fptr func;
};
inheritance02::inheritance02(double aa, double bb)
: Base02(aa)
, b(bb)
{
//func = double (*sol_aux)(double);
//func = &inheritance02::sol_aux;
}
//--------------------------------------------------
double inheritance02::sol_aux(double u)
{
return (a() + b) / u;
}
//--------------------------------------------------
double inheritance02::solution(double x, double t)
{
//inheritance01 LT (&func);
//inheritance01 LT (this->func);
//inheritance01 LT (&fptrsol_aux);
inheritance01 LT(func); // Here is the problem
return LT.calc(x + t);
}
//########################################################
#include <iostream>
int main()
{
inheritance02 obj(1.0, 1.0);
double value = obj.solution(1.0, 1.0);
std::cout << "value = " << value << std::endl;
return 0;
}
As the comment by #Eljay says, you are creating a typedef for a pointer to member function here:
typedef double (inheritance02::*fptr)(double u);
However, the constructor of inheritance01 takes a regular function pointer as an argument:
inheritance01( double (*ptr_f)(double));
so this line:
inheritance01 LT(func); // Here is the problem
doesn't work because the types don't match up (pointer to member functions are not convertible to function pointers).
The easy fix would be to make func a regular function pointer, like this:
typedef double (*fptr)(double u);
and everything should work fine.
Here's a demo.
Although I am not able to declare the 'func_' parameter as const and private (I do not know how to return a std::function) the following code solves my problem:
#include <iostream>
#include <functional>
using namespace std;
class Base01
{
public:
Base01( std::function<double (double)> );
virtual double calc( double ) = 0;
//function<double (double)> func { return func_; }
function<double (double)> func;
private:
//const function<double (double)> func_;
};
Base01::Base01( function<double (double)> f) : func(f) {}
//----------------------------------------------------
class inheritance01:public Base01
{
public:
inheritance01( function<double (double)> );
virtual double calc( double );
};
inheritance01::inheritance01 (function<double (double)> f): Base01(f){}
double inheritance01::calc(double t) { return Base01::func(2.0*t); }
//###################################################
class Base02
{
public:
Base02(double);
virtual double solution(double, double) = 0;
double a(){return a_;};
private:
const double a_;
};
Base02::Base02(double aa): a_(aa) {}
//------------------------------------------------------
class inheritance02 : public Base02
{
public:
inheritance02( double, double );
virtual double solution(double, double);
private:
double sol_aux (double);
const double b;
};
inheritance02::inheritance02 (double aa, double bb)
: Base02(aa), b(bb)
{}
//--------------------------------------------------
double inheritance02::sol_aux(double u) { return (a()+b)/u; }
//--------------------------------------------------
double inheritance02::solution(double x, double y)
{
inheritance01 LT ( bind( &inheritance02::sol_aux, this, placeholders::_1) );
return LT.calc(x+y);
}
//########################################################
int main()
{
inheritance02 obj (1.0,1.0);
double value = obj.solution(1.0,1.0);
std::cout << "value = " << value << std::endl;
return 0;
}

C2276 or C3867 compiler errors in C++

I need to send a class member function 'curve' to another function 'fun', but I get errors during compilation. How to code this correctly?
Using address '&' results in C2276, without using it - C3867.
class Test
{
public:
double v;
double curve(double x)
{
return x + v;
}
Test(double z)
{
v = z;
}
};
double fun(double(*f)(double), double x)
{
return f(x);
}
void main()
{
Test d(2.0);
double r = fun(&d.curve, 3.0);
}
curve is a member function of Test class so you need to have an instance of Test on which curve can be called.
You can change fun to take as first parameter pointer to member function and as second param pass a reference to Test instance, the result code may look like:
class Test {
public:
double v;
double curve(double x) {
return x + v;
}
Test(double z) {
v = z;
}
};
double fun( double(Test::*f)(double) , Test& obj, double x) {
return (obj.*f)(x);
}
int main()
{
Test d(2.0);
double r = fun(&Test::curve, d, 3.0);
}
If you can change the fun signature, the answer of rafix07 is perfect.
If you don't want to change the number of parameters of fun, you probably want to write something like that:
double fun(double(*f)(double), double x)
{
return f(x);
}
int main() // not void
{
Test d(2.0);
double r = fun([d](double double_){ return d.curve(double_); }, 3.0);
std::cout << r;
}
Sadly it doesn't work because a lambda can be stored in a function pointer only if it doesn't use a capture.
So you have 2 solutions:
1) the template
// Must be in .hpp
template <class T>
double fun(T f, double x)
{
return f(x);
}
int main() // not void
{
Test d(2.0);
double r = fun([d](double double_) mutable { return d.curve(double_); }, 3.0);
}
2) the std::function
#include <functional>
double fun(std::function<double(double)> f, double x)
{
return f(x);
}
Note: you have to use mutable because double curve(double x) is not const, I think it should be.

Is there a way to compound functions in C++?

General question :
If there are two objects A and B with respective functions f_A(arg list) and f_B(arg list).
What's the best way to create an object C with a function compounded of f_A(...) and f_B(...) ?
for example : f_C() = f_A() + f_B() or f_C() = f_A(f_B())
Is it possible to overload the "+" operator such that we can create the object C doing something like that ?
auto object_c = object_a + object_b
Here is a sample of my code :
class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double X,
double Y
)
{
double result;
result = m_scale * exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;
}
GaussianKernel operator+(const GaussianKernel& b) {
/*Here I would like to overload the + operator such that
I can create a kernel from two others kernels,
I mean with a covariance function compound of the previous ones
*/
}
private:
double m_sigma;
double m_scale;
};
Thanks you.
Given two methods f_A and f_B you can get f_C returning the sum of the others by using for example a lambda:
auto f_C = [](/*param*/){ return f_A(/*param*/) + f_B(/*param*/); };
auto sum_result = f_C(param);
To get the compound method it would be this:
auto f_C = [](/*param*/){ return f_B( f_A(/*param*/)); };
auto compound_result = f_C(param);
PS: I know that this is not directly applicable to your example, still trying to find out what exactly you want to do.
I would start with prototype solution like this:
class FooKernel : public Kernel {
public:
FooKernel (std::function<double(double, double)> fun) : fun_(fun) {}
double covarianceFunction(
double X,
double Y
) const {
return fun_(X, Y);
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
std::function<double(double, double)> fun_;
};
class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double X,
double Y
) const
{
double result;
result = m_scale * exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
double m_sigma;
double m_scale;
};
No longer lambdas are used, but now uses Your function as You wished.
Later on I would try to remove the std::function as it may have quite big performance impact. Instead I would make the FooKernel a class template, that stores callable by value.
I would suggest another subclass of Kernel:
class CompoundGaussianKernel : public Kernel {
public:
CompoundGaussianKernel(GaussianKernel const& kernel1, GaussianKernel const& kernel2)
: m_kernel1(kernel1), m_kernel2(kernel2)
{}
double covarianceFunction(double X, double Y)
{
return m_kernel1.covarianceFunction(X, Y) + m_kernel2.covarianceFunction(X, Y);
// or any other composition than "+"
}
private:
GaussianKernel m_kernel1;
GaussianKernel m_kernel2;
};
I recommend not to define operator+ inside of a class but as a free function.
CompoundGaussianKernel operator+(GaussianKernel const& kernel1, GaussianKernel const& kernel2)
{
return CompoundGaussianKernel(kernel1, kernel2);
}

C++ Intertwined #includes

First, I am a beginner in C++. Second, I'm sorry of this post turns out to be too long. I have a few classes that make use of each other, similar to this picture (a quick sketch):
And this is a quick sketch of a usable code. The formulas are bogus, but the functionality is close to the real problem. I omitted making source files for simplicity. The #includes are as they were after the last compile that got me the fewest errors...
"y.h"
#pragma once
#include "a.h"
#include "b.h"
class X;
class A;
class B;
class Y
{
private:
double m_y;
public:
Y(double b, double c):
{
if (c)
m_y = b*b;
else
m_y = sqrt(b);
if (b<0)
{
A::setP(m_y);
A::setQ(m_y + 1);
A::setR(m_y - 1);
}
else
{
B::setP(m_y);
B::setQ(m_y + 1);
B::setR(m_y - 1);
}
}
"a.h"
#pragma once
#include "x.h"
class X;
class A : virtual public X
{
private:
double m_p, m_q, m_r;
public:
A(double a, double b): m_p {a*a}
{
m_q = m_p + 0.5 * b;
m_r = m_q - m_p;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
"b.h"
#pragma once
#include "x.h"
class X;
class B : virtual public X
{
private:
double m_p, m_q, m_r;
public:
B(double a, double b): m_p {a + a}
{
m_q = m_p*m_p;
m_r = b + m_q;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
"x.h"
//#include "a.h"
class A;
class B;
class X
{
private:
double m_x1, m_x2;
public:
X(double a, double b, double c, int d): m_x1 {2*a}
{
double p, q, r;
switch (d)
{
case 1:
p = A::getP();
q = A::getQ();
r = A::getR();
m_x2 = p * b + q * c - r;
break;
case 2:
p = B::getP();
q = B::getQ();
r = B::getR();
m_x2 = (p - q) * b + r / c;
break;
}
}
double getX1() { return m_x1; }
double getX2() { return m_x2; }
};
"main.cpp"
#include "x.h"
#include <iostream>
int main()
{
X test {3.14, 0.618, 1.618, 1};
std::cout << test.getX1() << '\t' << test.getX2() << '\n';
return 0;
}
My problem is with the necessary includes (assume each class has a header and source file). For now, let's consider only class A in there. main.cpp only has #include x.h. To avoid repeating the code with all combinations, I'll try ennumerating what I did, so far:
#include a.h in class X, then #include y.h in class A, class Y has no #include, no forward declarations. The compiler complains about expected class name before { in both Y and A.
add forward declarations to the above => invalid use of incomplete type "class ..." in both Y and A.
do it backwards with #include a.h in class Y, then #include x.h in class A, class X has no #include, with forward declarations => incomplete type A used in nested name spacifier in class X, pointing at X(): { int x {A::funcA()} }.
as above and no forward declarations means errors everywhere.
Searches on the net said this happens because of cyclic dependencies, but how can that be since I am only including the previous or the next, never both? There were answers saying that using #pragma once instead of the usual may resolve the problems, I tried, it's the same incomplete type.... For reference only, I also tried looking at a few source codes (wxMaxima, audacious) to see how they did it, and it seems they used my first approach.
At this point, I am very confused. If the above can be used for an answer, can someone please give me some directions on how to properly use the #includes here? If not, please leave a comment and I'll delete this, if needed.

Abstracting a call to combine the results of a vector of classes

I've got a class which acts as a combiner of a vector of pointers to an abstract base class. In the combined class there is a lot of repetition of the function that is used to combine the member functions together, e.g.
class Base {
public:
virtual double foo1(double x) = 0;
virtual double foo2(double x) = 0;
};
class Combined : public Base {
std::vector< std::shared_ptr<Base> > bases;
public:
double foo1(double x) {
double rv = 0.0;
for( auto& b : bases ) {
rv += b->foo1(x);
}
return rv;
}
double foo2(double x) {
double rv = 0.0;
for( auto& b : bases ) {
rv += b->foo2(x);
}
return rv;
}
};
It feels like I should be able to write one function to abstract that pattern away from having to repeat it for every method, so the Combined could be written in a way such as
class Combined : public Base {
std::vector< std::shared_ptr<Base> > bases;
public:
double foo1(double x) {
return combiner(foo1, x);
}
double foo2(double x) {
return combiner(foo2, x);
}
};
and there would be a combiner function along the lines of
double combiner(FuncName f, double x)
{
double rv = 0.0;
for( auto& b : bases ) {
rv += b->f(x);
}
return rv;
}
To reduce the quantity of boilerplate
Any help would be greatly appreciated.
It's called std::accumulate (found in <numeric>) and it can do exactly this.
#include <iostream>
#include <memory>
#include <algorithm>
using namespace std;
struct iFoo {virtual double foo() const=0;};
struct A : public iFoo {virtual double foo() const{return 10;}};
struct B : public iFoo {virtual double foo() const{return 20;}};
std::vector<std::unique_ptr<iFoo>> foos;//pretend its a member variable i'm lazy
//pretend its a member function (again, lazy)
template <typename T,typename K>
T xform_accumulate(T init,K xformer)
{
return std::accumulate(foos.cbegin(),foos.cend(),init,[xformer](T a,const std::unique_ptr<iFoo>& b) {return a+xformer(b);});
}
int main()
{
foos.push_back(std::unique_ptr<iFoo>(new A()));
foos.push_back(std::unique_ptr<iFoo>(new B()));
double x = xform_accumulate( 0.0, [](const std::unique_ptr<iFoo>& x){return x->foo();});
cout << "Hello World" << x << endl;
return 0;
}