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

Tags:

C++

C++11