I asked a similar question a couple of hours ago about connecting two elements of a vector. Now, I would like to make my question more general. Let's assume that we have two objects of the type double namely double d1, d2
. We want the third object (double d3
) to obtain the value of d1+d2
, such that if we change d1
or d2
, then d3
automatically obtains the new value of d1+d2
. How can we do it in C++?
This is what I mean:
int main(){
double d1,d2,d3;
d1=4;
d2=7;
//some operations to make d3=d1+d2
std::cout<<d3<<endl;// I want it to print 11
d2=-4;
std::cout<<d3<<endl;//Now without any further operations between these line, it should print 0
return 0;
}
Thanks.
Using Draw, you can combine drawing objects together in two distinct ways: grouping and combining. These two methods allow you to treat multiple objects as one unit, or to merge objects to form a new shape. Grouping is like putting objects in a container. You can move them as a group and apply global changes to them.
An interaction between two objects which causes a push or pull is termed as force.
You can create a wrapper, as a lambda:
double d1 = 0, d2 = 0;
auto l = [&](){ return d1 + d2; };
l(); // 0
d1 = 40;
d2 = 2;
l(); // 42
If you want that all the variables has the same type, you may add a type-erasure wrapper as std::function
:
std::function<double()> f1 = [] { return 0; };
std::function<double()> f2 = [] { return 0; };
std::function<double()> sum = [&] { return f1() + f2(); };
std::cout << sum() << std::endl; // 0
f1 = [] { return 40; };
f2 = [] { return 2; };
std::cout << sum() << std::endl; // 42
Your problem is the classical motivation for parameter binding.
#include <iostream>
#include <functional>
//generic add
template <typename T>
void Add(T x, T y, T & z){
z = x + y;
}
int main(){
//z will change automatically in function call
double z = 0;
//bind z as the result
using namespace std::placeholders;
auto add = std::bind(Add<double>, _1, _2, std::ref(z));
//z is implicity passed and changed
add(6,4);
//outputs 10
std::cout << z << '\n';
}
bind and reference wrappers can help achieve the functionality you are after.
Write a wrapper, which will store pointers to double
s (as recommended in your original question). Beware, that this will not work, if double
s will go out of scope but counter
would not. Also, you can overload conversion to T
operator to get rid of total()
function.
template<typename T>
class counter
{
public:
void regist(T& d)
{
refs.push_back(&d);
}
T total()
{
T total{};
for (auto d : refs)
total += *d;
return total;
}
private:
std::vector<T*> refs;
};
int main(int argc, char* argv[])
{
double d1 = 1.6;
double d2 = 7.2;
double d3 = 1e-4;
counter<double> cnt;
cnt.regist(d1);
cnt.regist(d2);
cnt.regist(d3);
std::cout << cnt.total() << std::endl; // 8.8001
d2 = -7.1;
std::cout << cnt.total() << std::endl; // -5.4999
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With