【问题标题】:Why C++ does not allow function parameters used for default values latter parameters?为什么 C++ 不允许函数参数用于默认值后面的参数?
【发布时间】:2015-07-30 08:25:04
【问题描述】:

这是this question 的后续活动。那里的 OP 问题中的代码对我来说看起来非常合理且明确。为什么 C++ 不允许使用前面的参数来定义后面的参数的默认值,像这样:

int foo( int a, int b = a );

此外,至少在 C++11 中声明的参数类型可用于确定返回类型,因此以类似方式使用函数参数并非闻所未闻:

auto bar( int a ) -> decltype( a );

因此问题是:不允许上述foo 声明的原因是什么?

【问题讨论】:

  • 我能想到的一个原因是,为了保持理智,这需要对函数参数评估顺序进行约束,目前 C++ 中尚未定义。对于返回类型示例,这不是必需的。
  • 除了方便之外,如果您可以添加一种情况,即通过重载无法实现这一点,就像其他问题的答案一样,它会增加需要的大量燃料我>。在没有需要或向后兼容的情况下,标准委员会在特性添加方面有些保守。他们倾向于避开“为什么不呢?”支持更严格的“为什么”。
  • 附带说明:C++ 中使用的两个最流行的调用约定(__cdecl__stdcalldefine right-to-left order 的参数传递。如果您使用一些非平凡(包含自定义构造函数)参数作为函数参数并单步执行此类调用来调试代码,您会注意到,构造函数确实被以相反的顺序调用。
  • @Mateusz:调用约定指定参数的空间顺序,而不是构造它们的时间顺序。坚持空间秩序,使用完全不同的时间秩序来构建,完全没有问题。您可以看到时间顺序与调试构建中指定的空间顺序相匹配,这仅仅是因为编译器编写者选择了按该顺序构造参数。这并不意味着这也适用于发布版本,当然也不意味着编译器必须使用该顺序。
  • @MooseBoys 正是因为当前未指定评估顺序,所以允许对评估顺序施加部分限制的功能没有问题。所以这不可能是原因。我认为这就像 WhozCraig 写的那样:不允许这样做,因为没有足够的理由允许这样做。

标签: c++ language-lawyer default-parameters


【解决方案1】:

一方面,这需要在b 之前评估a,但是C++(如C)没有定义函数参数的评估顺序。

你仍然可以通过添加一个重载来获得你想要的效果:

int foo(int a, int b)
{ /* do something */ }

int foo(int a)
{ return foo(a, a); }

【讨论】:

  • 我看不出 C++ 没有指定评估顺序有什么关系。当使用此功能时,允许在以后的默认值中使用参数当然会强制执行一些偏序。但我不明白这会有什么问题。我认为不允许这样做的原因只是好处太小了。
猜你喜欢
  • 2018-04-30
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2015-02-20
  • 1970-01-01
相关资源
最近更新 更多