How can I make a variable always equal to the result of some calculations?

Edit: While I fully answered the question as asked, please have a look at Artelius' answer, too. It addresses some issues my answer doesn't (encapsulation, avoidance of redundancies, risks of dangling references). A possible optimisation, if calculation is expensive, is shown in Jonathan Mee's answer.


You mean something like this:

class Z
{
    int& x;
    int& y;
public:
    Z(int& x, int& y) : x(x), y(y) { }
    operator int() { return x + y; }
};

The class delays calculation of the result until casted as int. As cast operator is not explicit, Z can be used whenever an int is required. As there's an overload of operator<< for int, you can use it with e. g. std::cout directly:

int x, y;
Z z(x, y);
std::cin >> x >> y;
if(std::cin) // otherwise, IO error! (e. g. bad user input)
    std::cout << z << std::endl;

Be aware, though, that there's still a function call (the implicit one of the cast operator), even though it is not visible. And actually the operator does some true calculations (rather than just accessing an internal member), so it is questionable if hiding away the function call really is a good idea...


You can get close to this with by using a lambda in C++. Generally, when you set a variable like

int x;
int y;
int z{x + y};

z will only be the result of x + y at that time. You'd have to do z = x + y; every time you change x or y to keep it update.

If you use a lambda though, you can have it capture what objects it should refer to, and what calculation should be done, and then every time you access the lambda it will give you the result at that point in time. That looks like

int x;
int y;
auto z = [&](){ return x + y; };
cin >> x;
cin >> y;
cout << z();

and now z() will have the correct value instead of the uninitialized garbage that the original code had.

If the computation is very expensive you can even add some caching to the lambda to make sure you aren't running the computation when you don't need to. That would look like

auto z = [&](){ static auto cache_x = x; 
                static auto cache_y = y; 
                static auto cache_result = x + y;
                if (x != cache_x || y != cache_y)
                {
                    cache_x = x; 
                    cache_y = y; 
                    cache_result = x + y;
                }
                return cache_result;
};

The closest you probably can get is to create a functor:

#include <iostream>

int main() {
    int x;
    int y;

    auto z = [&x, &y] { return x + y; }; // a lambda capturing x and y

    while(true) {
        std::cin >> x;
        std::cin >> y;
        std::cout << z() << "\n";
    }
}

There are two chief techniques:

  1. Deferred calculation - instead of z being a simple variable, make it a function which calculates the value on demand (see other answers for examples). This can be source-code transparent if z is some proxy object with implicit conversion to the required type (as in Aconcagua's answer).

  2. Explicit notification of changes. This requires x and y to be observable types; when either changes value, then z updates itself (and notifies its observers if applicable).

The first version is usually preferred, but the second may be more appropriate if you need z to be an observable type.


This sounds like the XY problem (pun intended).

From the sound of it, you are not really writing code according to good object oriented practices. I would advise you not to use the "tricks" other people have suggested, but to actually learn how to make better use of OO structure.

Before I go into that, note that assignment is distinct from an equality relation. The = in C++ is assignment, which is not the same as the = in maths. There are some (but not many) programming languages that do support equality relations, but C++ is not one of them. The thing is, adding support for equality relations introduces a heap of new challenges, so it's not as simple as "why isn't it in C++ yet".

Anyway, in this case, you should probably be encapsulating your related variables in a class. Then you can use methods to obtain the "up-to-date" information. For example:

class Player {
    std::vector<int> inventory;
    int cash;
public:
    int inventory_total();
    int net_worth();
}

//adds up total value of inventory
int Player::inventory_total() {
    int total = 0;
    for(std::vector<int>::iterator it = inventory.begin(); it != inventory.end(); ++it) {
        total += *it;
    }
    return total;
}

//calculates net worth
int Player::net_worth() {
    //we are using inventory_total() as if it were a variable that automatically
    //holds the sum of the inventory values
    return inventory_total() + cash;
}


...


//we are using net_worth() as if it were a variable that automatically
//holds the sum of the cash and total holdings
std::cout << player1.net_worth();

I admit that adding this behaviour to a class is quite a bit more complicated than saying z = x + y, but it really is only a few extra lines of code.

That would be very annoying and error prone if you forgot to call the function somewhere.

In this case the object doesn't have a net_worth member variable, so you can't accidentally use it instead of calling the function.