为什么成员变量不能用作参数的默认值?

Bar*_*uch 6 c++ language-lawyer default-parameters

可能重复:
非静态成员作为非静态成员函数的默认参数

如果我错了,请纠正我,但我认为默认参数的工作方式如下:

当编译器看到函数调用时,它开始将参数压入堆栈.当参数耗尽时,它将开始将默认值推送到堆栈,直到填满所有必需参数(我知道这是一个简化,因为参数实际上是从右向左推送的,所以它将从默认值开始,但是想法是一样的).

如果这是真的,为什么不能将成员变量用作默认值?在我看来,由于编译器像往常一样在呼叫站点推送它们,它应该能够解决它们就好了!

编辑由于答案似乎被我的问题误解了,让我澄清一下.我知道情况就是这样,而且我知道该语言允许和不允许的内容.我的问题是为什么语言设计师选择不允许这样做,因为它似乎自然而然地起作用.

AnT*_*AnT 4

您所问问题的本质可以归纳为这个简单的示例

void foo(int a, int b = a);
Run Code Online (Sandbox Code Playgroud)

这在 C++ 中是不允许的。C++ 不允许默认参数依赖于其他参数。

使用类成员作为默认参数只是上述情况的一种特殊情况,因为类成员是通过this指针访问的,而this指针只是每个非静态成员函数的另一个隐藏参数。

所以,问题是为什么

void foo(int a, int b = a);
Run Code Online (Sandbox Code Playgroud)

不允许。

不允许这样做的一个明显的潜在原因是,它将对参数评估的顺序提出额外的要求。如您所知,在 C++ 中,函数参数求值的顺序是未指定的 - 编译器可以按任何顺序求值参数。但是,为了支持上述默认参数功能,编译器必须确保ab. 这感觉像是一个过高的要求,限制了我们在 C++ 中常见的评估顺序的典型自由度。

请注意,这

int a;

void foo(int b = a);
Run Code Online (Sandbox Code Playgroud)

在 C++ 中是允许的。并且,显然,它没有表现出上述的评估顺序问题。

  • @baruch:是的,但是如果 `c` 不是预先准备的变量,而是函数调用的结果,如 `obtain_c_from_somewhere().bar()` 中那样怎么办?调用该函数两次是不可接受的。在这种情况下,唯一的解决方案是始终确保*首先*调用“obtain_c_from_somewhere()”(以获取“this”),并且*稍后*准备其他参数。这正是我在回答中讨论的对评估顺序的附加要求。 (2认同)