Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nonstatic member as a default argument of a nonstatic member function [duplicate]

struct X {    X():mem(42){}    void f(int param = mem) //ERROR    {       //do something    } private:     int mem; }; 

Can anyone give me just one reason as to why this is illegal in C++?! That is to say, I know that it is an error, I know what the error means, I just can't understand why would this be illegal!

like image 881
Armen Tsirunyan Avatar asked Dec 27 '10 14:12

Armen Tsirunyan


People also ask

What is a nonstatic member function?

A non-static member function is a function that is declared in a member specification of a class without a static or friend specifier. ( see static member functions and friend declaration for the effect of those keywords)

What happens if non static members are used in static member function?

What happens if non static members are used in static member function? Explanation: There must be specific memory space allocated for the data members before the static member functions uses them. But the space is not reserved if object is not declared.

Can a static member function call non static member function of a class?

You cannot have static and nonstatic member functions with the same names and the same number and type of arguments. Like static data members, you may access a static member function f() of a class A without using an object of class A .

How do you call a non static method in C++?

You need a instance of the class to call non-static member functions. So simply, MyClass obj; obj. myClassMethod();


2 Answers

Default arguments have to be known at compile-time. When you talk about something like a function invocation, then the function is known at compile-time, even if the return value isn't, so the compiler can generate that code, but when you default to a member variable, the compiler doesn't know where to find that instance at compile-time, meaning that it would effectively have to pass a parameter (this) to find mem. Notice that you can't do something like void func(int i, int f = g(i)); and the two are effectively the same restriction.

I also think that this restriction is silly. But then, C++ is full of silly restrictions.

like image 27
Puppy Avatar answered Sep 20 '22 06:09

Puppy


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):

  • Default argument in the middle of parameter list?
like image 130
Nawaz Avatar answered Sep 19 '22 06:09

Nawaz