Nonstatic member as a default argument of a nonstatic member function

后端 未结 9 1032
攒了一身酷
攒了一身酷 2020-11-28 05:56
struct X
{
   X():mem(42){}
   void f(int param = mem) //ERROR
   {
      //do something
   }
private: 
   int mem;
};

Can anyone give me just one

相关标签:
9条回答
  • 2020-11-28 06:39

    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.

    0 讨论(0)
  • 2020-11-28 06:39

    For one reason, because f is public, but mem is private. As such, code like this:

    int main() { 
        X x;
        x.f();
        return 0;
    }
    

    ...would involve outside code retrieving X's private data.

    Aside from that, it would (or at least could) also make code generation a bit tricky. Normally, if the compiler is going to use a default argument, it gets the value it's going to pass as part of the function declaration. Generating code to pass that value as a parameter is trivial. When you might be passing a member of an object (possibly nested arbitrarily deeply) and then add in things like the possibility of it being a dependent name in a template, that might (for example) name another object with a conversion to the correct target type, and you have a recipe for making code generation pretty difficult. I don't know for sure, but I suspect somebody thought about things like that, and decided it was better to stay conservative, and possibly open thins up later, if a good reason was found to do so. Given the number of times I've seen problems arise from it, I'd guess it'll stay the way it is for a long time, simply because it rarely causes problems.

    0 讨论(0)
  • 2020-11-28 06:39

    As all the other answers just discuss the problem, I thought I would post a solution.

    As used in other languages without default arguments (Eg C# pre 4.0)

    Simply use overloading to provide the same result:

    struct X
    {
       X():mem(42){}
       void f(int param)
       {
          //do something
       }
       void f()
       {
          f(mem);
       }
    private: 
       int mem;
    };
    
    0 讨论(0)
提交回复
热议问题