13 KiB
[dcl.fct.default]
9 Declarations [dcl]
9.3 Declarators [dcl.decl]
9.3.4 Meaning of declarators [dcl.meaning]
9.3.4.7 Default arguments [dcl.fct.default]
If an initializer-clause is specified in aparameter-declaration thisinitializer-clause is used as a default argument.
[Note 1:
Default arguments will be used in calls where trailing arguments are missing ([expr.call]).
â end note]
[Example 1:
The declarationvoid point(int = 3, int = 4); declares a function that can be called with zero, one, or two arguments of typeint.
It can be called in any of these ways:point(1,2); point(1); point();
The last two calls are equivalent topoint(1,4) andpoint(3,4), respectively.
â end example]
A default argument shall be specified only in theparameter-declaration-clause of a function declaration or lambda-declarator or in atemplate-parameter ([temp.param]).
A default argument shall not be specified for a template parameter pack or a function parameter pack.
If it is specified in aparameter-declaration-clause, it shall not occur within adeclarator orabstract-declarator of aparameter-declaration.77
For non-template functions, default arguments can be added in later declarations of a function that have the same host scope.
Declarations that have different host scopes have completely distinct sets of default arguments.
That is, declarations in inner scopes do not acquire default arguments from declarations in outer scopes, and vice versa.
In a given function declaration, each parameter subsequent to a parameter with a default argument shall have a default argument supplied in this or a previous declaration, unless the parameter was expanded from a parameter pack, or shall be a function parameter pack.
[Note 2:
A default argument cannot be redefined by a later declaration (not even to the same value) ([basic.def.odr]).
â end note]
[Example 2: void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow// a parameter with a default argumentvoid f(int, int);void f(int, int = 7);void h() { f(3); // OK, calls f(3, 7)void f(int = 1, int); // error: does not use default from surrounding scope}void m() {void f(int, int); // has no defaults f(4); // error: wrong number of argumentsvoid f(int, int = 5); // OK f(4); // OK, calls f(4, 5);void f(int, int = 5); // error: cannot redefine, even to same value}void n() { f(6); // OK, calls f(6, 7)}template<class ... T> struct C {void f(int n = 0, T...);}; C c; // OK, instantiates declaration void C::f(int n = 0, int) â end example]
For a given inline function defined in different translation units, the accumulated sets of default arguments at the end of the translation units shall be the same; no diagnostic is required.
If a friend declaration D specifies a default argument expression, that declaration shall be a definition and there shall be no other declaration of the function or function template which is reachable from D or from which D is reachable.
The default argument has the same semantic constraints as the initializer in a declaration of a variable of the parameter type, using the copy-initialization semantics ([dcl.init]).
The names in the default argument are looked up, and the semantic constraints are checked, at the point where the default argument appears, except that an immediate invocation ([expr.const]) that is a potentially-evaluated subexpression ([intro.execution]) of the initializer-clause in a parameter-declaration is neither evaluated nor checked for whether it is a constant expression at that point.
Name lookup and checking of semantic constraints for default arguments of templated functions are performed as described in [temp.inst].
[Example 3:
In the following code,g will be called with the valuef(2):int a = 1;int f(int);int g(int x = f(a)); // default argument: f(::a)void h() { a = 2; {int a = 3; g(); // g(f(::a))}}
â end example]
[Note 3:
A default argument is a complete-class context ([class.mem]).
Access checking applies to names in default arguments as described in [class.access].
â end note]
Except for member functions of templated classes, the default arguments in a member function definition that appears outside of the class definition are added to the set of default arguments provided by the member function declaration in the class definition; the program is ill-formed if a default constructor ([class.default.ctor]), copy or move constructor ([class.copy.ctor]), or copy or move assignment operator ([class.copy.assign]) is so declared.
Default arguments for a member function of a templated class shall be specified on the initial declaration of the member function within the templated class.
[Example 4: class C {void f(int i = 3); void g(int i, int j = 99);};
void C::f(int i = 3) {} // error: default argument already specified in class scopevoid C::g(int i = 88, int j) {} // in this translation unit, C::g can be called with no arguments â end example]
[Note 4:
A local variable cannot be odr-used ([basic.def.odr]) in a default argument.
â end note]
[Example 5: void f() {int i; extern void g(int x = i); // errorextern void h(int x = sizeof(i)); // OK// ...} â end example]
[Note 5:
The keywordthis cannot appear in a default argument of a member function; see [expr.prim.this].
[Example 6: class A {void f(A* p = this) { } // error}; â end example]
â end note]
A default argument is evaluated each time the function is called with no argument for the corresponding parameter.
A parameter shall not appear as a potentially-evaluated expression in a default argument.
[Note 6:
Parameters of a function declared before a default argument are in scope and can hide namespace and class member names.
â end note]
[Example 7: int a;int f(int a, int b = a); // error: parameter a used as default argumenttypedef int I;int g(float I, int b = I(2)); // error: parameter I foundint h(int a, int b = sizeof(a)); // OK, unevaluated operand â end example]
A non-static member shall not be designated in a default argument unless
it is designated by the id-expression or splice-expression of a class member access expression ([expr.ref]),
it is designated by an expression used to form a pointer to member ([expr.unary.op]), or
it appears as the operand of a reflect-expression ([expr.reflect]).
[Example 8:
The declaration ofX::mem1() in the following example is ill-formed because no object is supplied for the non-static memberX::a used as an initializer.
int b;class X {int a; int mem1(int i = a); // error: non-static member a used as default argumentint mem2(int i = b); // OK, use X::bconsteval void mem3(std::meta::info r = ^^a) {} // OKint mem4(int i = [:^^a:]); // error: non-static member a designated in default argumentstatic int b;};
The declaration ofX::mem2() is meaningful, however, since no object is needed to access the static memberX::b.
Classes, objects, and members are described in [class].
â end example]
A default argument is not part of the type of a function.
[Example 9: int f(int = 0);
void h() {int j = f(1); int k = f(); // OK, means f(0)}int (*p1)(int) = &f;int (*p2)() = &f; // error: type mismatch â end example]
[Note 7:
When an overload set contains a declaration of a function whose host scope is S, any default argument associated with any reachable declaration whose host scope is S is available to the call ([over.match.viable]).
â end note]
[Note 8:
The candidate might have been found through a using-declarator from which the declaration that provides the default argument is not reachable.
â end note]
A virtual function call ([class.virtual]) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object.
An overriding function in a derived class does not acquire default arguments from the function it overrides.
[Example 10: struct A {virtual void f(int a = 7);};struct B : public A {void f(int a);};void m() { B* pb = new B; A* pa = pb; pa->f(); // OK, calls pa->B::f(7) pb->f(); // error: wrong number of arguments for B::f()} â end example]
This means that default arguments cannot appear, for example, in declarations of pointers to functions, references to functions, ortypedef declarations.