Your code (simplified):
struct X
{
int mem;
void f(int param = mem); //ERROR
};
You want to use a non-static member data as default value for a parameter of a member function. The first question which comes to mind is this : which specific instance of the class the default value mem
belongs to?
X x1 = {100}; //mem = 100
X x2 = {200}; //mem = 200
x1.f(); //param is 100 or 200? or something else?
Your answer might be 100
as f()
is invoked on the object x1
which has mem = 100
. If so, then it requires the implementation to implement f()
as:
void f(X* this, int param = this->mem);
which in turn requires the first argument to be initialized first before initialization of other argument. But the C++ standard doesn't specify any initialization order of the function arguments. Hence that isn't allowed. Its for the same reason that C++ Standard doesn't allow even this:
int f(int a, int b = a); //§8.3.6/9
In fact, §8.3.6/9 explicitly says,
Default arguments are evaluated each
time the function is called. The order
of evaluation of function arguments is
unspecified. Consequently, parameters
of a function shall not be used in
default argument expressions, even if
they are not evaluated.
And rest of the section is an interesting read.
An interesting topic related to "default" arguments (not related to this topic though):
.size()
of classstd::string
, of the membersome_member_variable
. This is all that is needed. Overload resolution is done without taking default arguments into account (otherwise we would have circular dependency). So by the time we substitute the default argument, I think we know what object we need to touch the member of. – Monatomicf
with default arguments0
and1
respectively:int i; void f(int j = i) { } void g() { i = 0; f(); i = 1; f(); }
. – Monatomic