For example, why I cannot write this:
void f(double x, double y = x);
to declare a function f
, for which the call f(x)
is equivalent to f(x,x)
?
In case this doesn't seem useful to you, here's a possible usage scenario. In this example, I declare f
as follows:
void f(double x, double y = expensiveComputation(x));
where expensiveComputation
denotes, you guessed it, a function that does a very slow computation. I want to give the user of f
the possibility of passing in the value of y
if he has computed it previously, so I don't have to compute it again inside f
. Now, of course I can also resolve this by writing two overloads:
void f(double x, double y);
void f(double x) { f(x, expensiveComputation(x)); }
but writing overloads becomes tiresome as the number of arguments grows. For example, try to write:
void f(double x, double p = expensiveComputation(x),
double q = expensiveComputation2(x, p),
double r = expensiveComputation3(x, p, q),
double s = expensiveComputation3(x, p, q, r));
using overloads. It's just uglier. Default arguments are sexy. Is there a deeper syntactic reason why previous arguments can't be used to define argument default values?
A default argument is a value provided in a function declaration that is automatically assigned by the compiler if the calling function doesn't provide a value for the argument. In case any value is passed, the default value is overridden.
Characteristics for defining the default argumentsThe values passed in the default arguments are not constant. These values can be overwritten if the value is passed to the function. If not, the previously declared value retains. During the calling of function, the values are copied from left to right.
What we can't place followed by the non-default arguments? Explanation: To avoid the ambiguity in arguments.
Default arguments are only allowed in the parameter lists of function declarations and lambda-expressions, (since C++11) and are not allowed in the declarations of pointers to functions, references to functions, or in typedef declarations.
I don't know why default argument can't go that way, but maybe you can try to wrap all those arguments in a struct(class)?
struct ParamSet
{
double x;
double p;
double q;
ParamSet(double x)
: x(x)
, p(ExpensiveCompute1(x))
, q(ExpensiveCompute2(x, p))
{
}
ParamSet(double x, double p)
: x(x)
, p(p)
, q(ExpensiveCompute2(x, p))
{
}
ParamSet(double x, double p, double q)
: x(x), p(p), q(q)
{
}
private:
double ExpensiveCompute1(double x) {}
double ExpensiveCompute2(double x, double p) {}
};
void f(ParamSet ps);
Still need ctor overloads, but no more works than writing the expensiveComputation()
series like you provided, and at least all things are wrapped in the struct
Also, signature of f()
could be fixed, and there is only 1 version.
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