Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I cannot use previous argument values to define argument default values?

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?

like image 568
becko Avatar asked Aug 16 '15 22:08

becko


People also ask

When can any argument have a default value?

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.

Which are the rules for default arguments?

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 Cannot be placed by non default arguments?

What we can't place followed by the non-default arguments? Explanation: To avoid the ambiguity in arguments.

What can be used as a default function argument?

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.


1 Answers

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.

like image 79
Marson Mao Avatar answered Nov 03 '22 01:11

Marson Mao