简体   繁体   English

为什么允许这些默认参数?

[英]Why are these default arguments allowed?

I've found this question, and I'm completely baffled. 我发现了这个问题,我完全感到困惑。

The answer says b is invalid, "Non-static members can not be used as default arguments.". 答案是b无效,“非静态成员不能用作默认参数。” That makes perfect sense. 这很有道理。

What I don't understand is why the other two are okay. 我不明白的是为什么其他两个都没问题。 In fact, I'm struggling to understand what the semantics are if the default is not a constant expression... 事实上,如果默认值不是常量表达式,我很难理解语义是什么......

What's going on here? 这里发生了什么? Default parameters are clearly evaluated at compile time. 在编译时清楚地评估默认参数。 Does the compiler simply pick the current value? 编译器只是选择当前值吗?

#include <iostream>

int g_x = 44; 

struct Foo 
{ 
  int m_x; 
  static int s_x; 

  Foo(int x) : m_x(x) {} 
  int a(int x = g_x) { return x + 1; } 
  int b(int x = m_x) { return x + 1; }
  int c(int x = s_x) { return x + 1; }
}; 

int Foo::s_x = 22; 

int main(int argc, char** argv) 
{ 
  Foo f(6); 

  std::cout << f.a() << std::endl; 
  std::cout << f.b() << std::endl; 
  std::cout << f.c() << std::endl; 

  return 0; 
}

Actually, default arguments are evaluated when the function is called, which is why this is okay. 实际上,在调用函数时会计算默认参数,这就是为什么这是可以的。 From the draft C++ standard section 8.3.6 Default arguments which says ( emphasis mine going forward ): 草案C ++标准部分8.3.6 默认参数说( 强调我的前进 ):

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 a default argument, even if they are not evaluated. 因此,函数的参数不应在默认参数中使用,即使它们未被评估。 Parameters of a function declared before a default argument are in scope and can hide namespace and class member names. 在默认参数之前声明的函数的参数在范围内,并且可以隐藏命名空间和类成员名称。

The following example from the same section gives us a rationale for why we can use static members but not non-static ones: 以下来自同一部分的示例为我们提供了一个理由,说明为什么我们可以使用静态成员而不是非静态成员:

[ Example: the declaration of X::mem1() in the following example is ill-formed because no object is supplied for the non-static member X::a used as an initializer. [示例:以下示例中的X :: mem1()声明格式错误,因为没有为用作初始值设定项的非静态成员X :: a提供对象。

 int b; class X { int a; int mem1(int i = a); // error: non-static member a // used as default argument int mem2(int i = b); // OK; use X::b static int b; }; 

The declaration of X::mem2() is meaningful, however, since no object is needed to access the static member X::b. 但是,X :: mem2()的声明是有意义的,因为访问静态成员X :: b不需要任何对象。 Classes, objects, and members are described in Clause 9. —end example ] 类,对象和成员在第9章中描述.-结束示例]

Default arguments aren't evaluated at compile time. 在编译时不会计算默认参数。 They're evaluated each time a function call requires them. 每次函数调用需要它们时都会对它们进行评估。 They can be any expression that's valid in the context of the function declaration and has a suitable type, except that it can't use any other parameters (including this , in the case of a member function). 它们可以是在函数声明的上下文中有效且具有合适类型的任何表达式,除了它不能使用任何其他参数(在成员函数的情况下包括this参数)。

That restriction is because the evaluation order isn't specified, so there's no way to ensure a parameter value is available if it were needed to evaluate another argument. 这种限制是因为未指定评估顺序,因此如果需要评估另一个参数,则无法确保参数值可用。

I think this is understandable: g_x and s_x are available at compile time but this (and therefore this->m_x) is not. 我认为这是可以理解的:g_x和s_x在编译时可用但是这个(因此this-> m_x)不可用。 You can use a trick to use m_x: 您可以使用技巧来使用m_x:

int b(int x = -1) { return x == -1 ? m_x + 1 : x + 1; }

(Of course -1 should be illegal input in this case.) (在这种情况下,-1当然应该是非法输入。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么默认参数后允许参数包? - Why is a parameter pack allowed after default arguments? 为什么Stroustrup的书会演示默认的函数模板参数,这在当时是不允许的? - Why does Stroustrup's book demonstrate default function template arguments, which weren't allowed at the time? 为什么默认参数的警告? - Why the warning for default arguments? 为什么不允许使用此默认模板参数? - Why is this default template parameter not allowed? 为什么默认参数后跟一个? - Why are default arguments trailing ones? 由于允许哪个版本的C ++是默认参数? - Since which version of C++ are default arguments allowed? 为什么使用此指针作为默认参数指向不允许的函数? - Why using a pointer of this as default parameter to a function not allowed? 为什么立即函数默认不是 noexcept,为什么它们允许为 noexcept(false)? - Why immediate functions are not noexcept by default and why are they allowed to be noexcept(false)? 为什么现有的函数参数不能用于评估其他默认参数? - Why existing function arguments cannot be used to evaluate other default arguments? 为什么允许在类之外指定默认值但不在其中? - Why specifying the default value outside of a class is allowed but not inside it?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM