How to avoid copies with move - c++

I need to create a functor with parameters and call it in an accessor - I'm hoping that the compiler will optimize away the code for speed. Here is my attempt:
struct X {
X(int a, float b) : _a(a), _b(b) {}
float operator()(float value) const { /* do something */; }
int _a;
float _b;
};
struct Y {
Y(const X&& x) : _x(move(x)) {}
float operator()(float value) const { return _x(value); }
const X&& _x;
};
which I call thus in an accessor of some Object of class Value:
float getValue() const {
X x(2, 3.14);
Y y(move(x));
return y(_value);
}
Is this the best way to code this, or can it be done in a simpler way?

Related

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);
}

Link public and private variables (with write access to private variables)

I am currently rewriting C code into C++ code. While doing that I am replacing structs with classes. That means that some of the variables go from public to private. Now during the transition phase I want to do some error checking by compiling the program sometimes and running it. Thus I intended to have public and private variables at the same time, which are linked, i.e. when I write something into the private variable, the public variable also changes. Nevertheless I only want to write to the private variables by using separate functions, i.e. having the public variables as read-only variables. My current approach is:
#include <iostream>
#include <stdio.h>
class test_vec
{
private:
int x, y;
int data[2];
public:
int x_ext, y_ext;
int data_ext[2];
test_vec(int x, int y)
{
this->x = x;
this->y = y;
this->x_ext = this->x;
this->y_ext = this->y;
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
};
int main(void)
{
std::cout << "Hello World\n";
test_vec test(1, 2);
printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//So far, so good
test.set_x(4);
test.set_y(10);
printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//Not updated!
return 0;
}
How can I change the links between the variables? At the moment I already have two pointers copied into each other, but how can I "lock" the external variable onto the internal variable?
Not sure if it's a good design pattern since inline getters are fast but you could create constant references to your private variables:
class test_vec
{
private:
int x, y;
int data[2];
public:
const int &x_ext, &y_ext;
int data_ext[2];
// you have to initialize the references before constructor body
// references cannot be let uninitialized
test_vec(int x, int y) : x_ext(this->x), y_ext(this->y)
{
this->x = x;
this->y = y;
}
~test_vec()
{}
inline void set_x(int x)
{
this->x = x;
}
inline void set_y(int y)
{
this->y = y;
}
};
when x or y changes x_ext and y_ext follow:
Hello World
test has the properties (1, 2)
test has the properties (4, 10)
Bonus: constant references cannot be modified. That's the closest thing of a read property that you got here :)
If you don't want that restriction, just remove the const qualifier, but since you're encouraging encapsuation now that you have C++ I would let it as is and let the writers hit the wall on that (not to mention a good sed/regex replacement could refactor all your writes automatically)
You can use references for these purposes.
Say you have this setup:
class myclass{
public:
myclass(int pa, float pb);
int get_a() const {return a;}
float get_b() const {return b;}
void set_a(int v) {a=v;}
void set_b(float v) {b=v;}
private:
//These are the real values, private
int a;
float b;
public:
//These are the references, public
int& ref_to_a;
float& ref_to_b;
}
myclass::myclass(int pa, float pb)
:a(pa), b(pb), ref_to_a(a), ref_to_b(b)
{
}
You can go like this:
myclass c(33, 12.3f);
c.set_a(12);
c.set_b(111.1f);
//This...
std::cout<<c.ref_to_a<<" "<<c.ref_to_b<<std::endl;
//Should be the same as this...
std::cout<<c.get_a()<<" "<<c.get_b()<<std::endl;
Notice the access settings: the references are public, meaning you can write and read from them. If you want them to be read only you can play with the constness.
I wouldn't bother. Just make the members public for the moment, and when you have fixed all the external references, make them private.
class test_vec
{
public: // For now. Will become private later
int x, y;
public: // For now.
int data[2];
public: // For ever
test_vec(int x, int y)
: x(x), y(y) // Prefer initialization to assignment.
{
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
int get_x() const { return x; } // etc
};
If you really wanted to, you could make x_ext be a reference to const - but it's much more idiomatic in C++ to make getters be functions.
class test_vec
{
private:
int x, y;
int data[2];
public:
int const& x_ext;
int const& y_ext;
test_vec(int x_, int y_)
: x(x_), y(y_)
, x_ext(x), y_ext(y) // You *have* to use initialization here.
{
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
};

Reference in place of getters?

in C++ is it a bad practice to use reference in place of getters?
for example:
class X
{
int mP;
public:
const int& P;
X():P(mP){}
};
and later
X xl;
int h = xl.P;
Just think about refactoring to make the access thread safe, that won't work well this way and require a lot of changes in the client classes/functions.
If you have class members, that are guaranteed not to be changed over lifetime of the instance, you can simply provide const int P; and initialize it properly in your class' constructors.
If the value is to be visible class wide use a static const int P;
In any other case use a public getter:
int P() const; // a return type of 'const int &' would be redundant
1st shot implementation:
int X::P() const
{
return mP;
}
Thread safe implementation:
class X {
{
// ...
private:
// ...
mutable std::mutex internalDataGuard;
};
int X::P() const
{
std::lock(internalDataGuard);
return mP;
}
None of this is good:
class X { public: int x; };
class X {
private: int m_x;
public: const int& get() const { return m_x; }
public: void set(const int& other) { m_x = other; }
};
class X {
private: int m_x;
public: const int& x() const { return m_x; }
public: void x(const int& other) { m_x = other; }
};
class X {
private: int m_x;
public: const int& x() const { return m_x; }
public: int& x() { return m_x; }
};
Pick one, it's a design decision.
Having 'const int& x' to publish the private member will work:
class X {
private: int m_x;
public: const int& x;
public: X() : m_x(0), x(m_x) {}
// Take care for copy and assignment
};
The cost is a larger memory footprint.

C++0x Designated Initializers

I could find a way to do Designated Initializers in C++0x with only one member initializing.
Is there a way for multiple member initializing ?
public struct Point3D
{
Point3D(float x,y) : X_(x) {}
float X;
};
I want :
public struct Point3D
{
Point3D(float x,y,z) : X_(x), Y_(y), Z_(z) {}
float X_,Y_,Z_;
};
You have a few mistakes in your constructor, here is how you should write it:
/* public */ struct Point3D
// ^^^^^^
// Remove this if you are writing native C++ code!
{
Point3D(float x, float y, float z) : X_(x), Y_(y), Z_(z) {}
// ^^^^^ ^^^^^
// You should specify a type for each argument individually
float X_;
float Y_;
float Z_;
};
Notice, that the public keyword in native C++ has a meaning which is different from the one you probably expect. Just remove that.
Moreover, initialization lists (what you mistakenly call "Designated Initializers") are not a new feature of C++11, they have always been present in C++.
#Andy explained how you should be doing this if you're going to define your own struct.
However, there is an alternative:
#include <tuple>
typedef std::tuple<float, float, float> Point3D;
and then define some function as:
//non-const version
float& x(Point3D & p) { return std::get<0>(p); }
float& y(Point3D & p) { return std::get<1>(p); }
float& z(Point3D & p) { return std::get<2>(p); }
//const-version
float const& x(Point3D const & p) { return std::get<0>(p); }
float const& y(Point3D const & p) { return std::get<1>(p); }
float const& z(Point3D const & p) { return std::get<2>(p); }
Done!
Now you would use it as:
Point3D p {1,2,3};
x(p) = 10; // changing the x component of p!
z(p) = 10; // changing the z component of p!
Means instead of p.x, you write x(p).
Hope that gives you some starting point as to how to reuse existing code.

Real functions implementation in C++ and operator+ overloading

I would like to implement real functions in C++. In particular I would like to evaluate, differentiate, add, multiply such objects. Here is my implementation
class RealFunc {
public:
virtual int Eval(const double& x, double& result) = 0;
virtual int Diff(const double& x, double& result) = 0;
};
class Sqrt : public RealFunc {
public:
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
};
int Sqrt::Eval(const double& x, double& result) {
if(x<0) return 0;
else {
result = sqrt(x);
return 1;
}
};
int Sqrt::Diff(const double& x, double& result) {
if(x<=0) return 0;
else {
result = 0.5/sqrt(x);
return 1;
}
};
It gets tricky when I try to add RealFunc objects. I have to create a sum class that inherits from RealFunc
RealFunc operator+(const RealFunc& f, const RealFunc& g) {
Sum_RealFunc h(f,g);
return h;
};
class Sum_RealFunc : public RealFunc {
public:
Sum_RealFunc(const RealFunc& f_, const RealFunc& g_) : f(f_), g(g_) {};
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
private:
RealFunc f;
RealFunc g;
};
int Sum_RealFunc::Eval(const double& x, double& result) {
double temp_f,temp_g;
int success_f,success_g;
success_f = f.Eval(x,temp_f);
success_g = g.Eval(x,temp_g);
result = temp_f+temp_g;
return success_f*success_g;
};
// Same for Sum_RealFunc::Diff
My issue here is that I cannot use f,g as members in Sum_RealFunc since RealFunc is abstract... How should I proceed to get a clean implementation ?
PS : The code I put is a light version of what I am working on (functions from RxR->R with all differentiation directions, finite difference if stepsize member is not zero and other side functions)
The problem you are facing is that you need both a feature that works well with value objects (operator overloading) and features that only works with pointers (inheritance/polymorphism).
As a solution, you'd need to have a value object with overloaded operators as a wrapper for polymorphic objects managed via pointers:
class RealFuncImpl {
public:
virtual ~RealFuncImpl(); // don't forget this for polymorphic objects
virtual int Eval(const double& x, double& result) = 0;
virtual int Diff(const double& x, double& result) = 0;
};
class RealFunc {
std::shared_ptr<RealFuncImpl> impl;
public:
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
};
You'd derive your Sum_RealFuncImpl from RealFuncImpl and implement your operators for RealFunc. You should probably hide away your Impl classes in some "detail" namespace, as your code's end user should never see them.
EDIT:
Your Sum_RealFuncImpl would contain two std::shared_ptr<RealFuncImpl> members.
Try
class Sum_RealFunc : public RealFunc {
public:
Sum_RealFunc(RealFunc& f_, RealFunc& g_) : f(f_), g(g_) {};
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
private:
RealFunc& f;
RealFunc& g;
};
Now f and g are refernces instead which is fine.
Since you initialize them in the constructors initializer list, you can make the member variables references.
You have two possibilities:
Do as wolfgang suggested: use only a wrapper around a shared pointer. This way you can create copies without really having to copy the derived function objects.
Make the derived classes themselves copyable through a base-class pointer, by implementing a clone member. That's most conveniently done with deriving from a CRTP class instead of directly from the base class. I'd make it a local class, to not confuse things:
struct RealFunc {
virtual std::pair<double,bool> operator() //IMO better than this
(double x)const =0; // reference-argument hackery
virtual std::pair<double,bool> Diff
(double x)const =0;
virtual RealFunc* clone()const =0;
template<class Derived>
struct implementation : RealFunc {
RealFunc* clone() {
return new Derived(*static_cast<const Derived*>(this));
}
};
virtual ~RealFunc(){}
};
Now you just have to derive your function objects from implementation, to make them clonable:
struct Sqrt : RealFunc::implementation<Sqrt> {
std::pair<double,bool> operator()(double x) {
return x>=0
? std::make_pair(sqrt(x), true)
: std::make_pair(0., false);
}
...
}
Your sum function can now be done nicely with std::unique_ptr:
class Sum_RealFunc : public RealFunc::implementation<Sum_RealFunc> {
std::vector<std::unique_ptr<RealFunc>> summands;
public:
std::pair<double,bool> operator()(double x) {
double result=0;
for(auto& f: summands) {
auto r = (*f)(x);
if(r.second) result += r.first;
else return std::make_pair(0., false);
}
return std::make_pair(result, true);
}
Sum_RealFunc(const Sum_RealFunc& cpy) {
for(auto& f: cpy.summands)
summands.push_back(f->clone());
}
//friend operator+=(RealFunc& acc, const RealFunc& add); //doesn't work
};
Unfortunately, this is not enough indirection to allow writing simple sum expressions. I did something in a recent project that solved pretty much all of these issues, but was yet a bit more complicated: I gave every instance the option to override its behaviour with any other instance. Like
class RealFunc {
std::unique_ptr<RealFunc> override;
public:
virtual std::pair<double,bool> operator()(double x)const {
return (*override)(x);
}
virtual std::pair<double,bool> Diff(double x)const {
return override->Diff(x);
}
auto implemented() -> RealFunc* {
return implement_override? override->implemented() : this; }
auto implemented()const -> const RealFunc* {
return implement_override? override->implemented() : this; }
virtual RealFunc* clone()const =0;
template<class Derived>
struct implementation : RealFunc {
virtual std::pair<double,bool> operator()(double x)const =0;
virtual std::pair<double,bool> Diff(double x)const =0;
RealFunc* clone() {
return new Derived(*static_cast<const Derived*>(this));
}
};
virtual ~RealFunc(){}
};
That's not all, you need to include a lot of checks for override everywhere with this approach. But in the end, it allows you to combine functions very smoothly, like
RealFunc f = const_realfunc(7.);
for(auto& omega: omegas)
f += sine_angfreq(omega);
RealFunc g = f + noise_func(.3);
...