It couldn't work because it has to produce a single value after evaluation? |
Yes. A variable of type
double
can only store a value of type
double
. To store an expression would require something different.
You can kind of fake it with
lambda expressions ...
1 2 3 4 5
|
auto perimeter = [&](){ return width + length; };
auto surface = [&](){ return 2 * (width + length); };
std::cout << "the perimeter is " << perimeter() << '\n';
std::cout << "the surface is " << surface() << '\n';
|
... but what happens here behind the scenes is that it creates class objects that contains references to the captured variables
width and
length and it overloads the
function call operator so that you can "call" the object as if it were a function to calculate the value.
Without a lambda expression it would look something like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
class Perimeter
{
public:
Perimeter(double& width, double& length)
: w(width),
l(length)
{
}
double operator()() const
{
return w + l;
}
private:
double& w;
double& l;
};
Perimeter perimeter{width, length};
std::cout << "the perimeter is " << perimeter() << '\n'; // <-- same as before
|
This might be an alternative if you only intend to use them inside a single function. Regular functions and classes are however easier to reuse across different functions.
Another question, If I want to use uniform initialization, is my code efficient / acceptable enough? |
It looks fine except you should generally try to declare variables as late as possible, in the smallest scope possible. Preferably when you have a sensible value to initialize them with.
The declarations of
width and
length might be moved down a few lines (but it's not a big deal).
With
perimeter and
surface it's better to declare them when you calculate their values.
1 2
|
double perimeter = width + length;
double surface = 2 * (width + length);
|
Or if you prefer the "uniform initialization" syntax:
1 2
|
double perimeter { width + length };
double surface { 2 * (width + length) };
|