[dcl.fct.default]

# 9 Declarations [[dcl]](./#dcl)

## 9.3 Declarators [[dcl.decl]](dcl.decl#dcl.fct.default)

### 9.3.4 Meaning of declarators [[dcl.meaning]](dcl.meaning#dcl.fct.default)

#### 9.3.4.7 Default arguments [dcl.fct.default]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4263)

If an [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") is specified in a[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") this[*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") is used as a default argument[.](#1.sentence-1)

[*Note [1](#note-1)*:

Default arguments will be used in calls
where trailing arguments are missing ([[expr.call]](expr.call "7.6.1.3 Function call"))[.](#1.sentence-2)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4273)

[*Example [1](#example-1)*:

The declarationvoid point(int = 3, int = 4); declares a function that can be called with zero, one, or two arguments of typeint[.](#2.sentence-1)

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[.](#2.sentence-3)

â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4294)

A default argument shall be specified only in the[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of a function declaration
or [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") or in a[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]") ([[temp.param]](temp.param "13.2 Template parameters"))[.](#3.sentence-1)

A default argument shall not be specified for
a template parameter pack or
a function parameter pack[.](#3.sentence-2)

If it is specified in a[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]"),
it shall not occur within a[*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") or[*abstract-declarator*](dcl.name#nt:abstract-declarator "9.3.2 Type names [dcl.name]") of a[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")[.](#3.sentence-3)[77](#footnote-77 "This means that default arguments cannot appear, for example, in declarations of pointers to functions, references to functions, or typedef declarations.")

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4321)

For non-template functions, default arguments can be added in later
declarations of a
function that have the same host scope[.](#4.sentence-1)

Declarations that have different
host scopes have completely distinct sets of default arguments[.](#4.sentence-2)

That
is, declarations in inner scopes do not acquire default
arguments from declarations in outer scopes, and vice versa[.](#4.sentence-3)

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[.](#4.sentence-4)

[*Note [2](#note-2)*:

A default argument
cannot be redefined by a later declaration
(not even to the same value) ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#4.sentence-5)

â *end note*]

[*Example [2](#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<int> 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[.](#4.sentence-6)

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[.](#4.sentence-7)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4375)

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]](dcl.init "9.5 Initializers"))[.](#5.sentence-1)

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]](expr.const "7.7 Constant expressions")) that
is a potentially-evaluated subexpression ([[intro.execution]](intro.execution "6.10.1 Sequential execution")) of
the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") in a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") is
neither evaluated
nor checked for whether it is a constant expression at that point[.](#5.sentence-2)

Name lookup and checking of semantic constraints for default
arguments of templated functions are performed as described in [[temp.inst]](temp.inst "13.9.2 Implicit instantiation")[.](#5.sentence-3)

[*Example [3](#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](#note-3)*:

A default argument is a complete-class context ([[class.mem]](class.mem "11.4 Class members"))[.](#5.sentence-5)

Access checking applies to names in default arguments as
described in [[class.access]](class.access "11.8 Member access control")[.](#5.sentence-6)

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4419)

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]](class.default.ctor "11.4.5.2 Default constructors")),
copy or move constructor ([[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors")), or
copy or move assignment operator ([[class.copy.assign]](class.copy.assign "11.4.6 Copy/move assignment operator"))
is so declared[.](#6.sentence-1)

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[.](#6.sentence-2)

[*Example [4](#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*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4444)

[*Note [4](#note-4)*:

A local variable cannot be odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule"))
in a default argument[.](#7.sentence-1)

â *end note*]

[*Example [5](#example-5)*: void f() {int i; extern void g(int x = i); // errorextern void h(int x = sizeof(i)); // OK// ...} â *end example*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4460)

[*Note [5](#note-5)*:

The keywordthis cannot appear in a default argument of a member function;
see [[expr.prim.this]](expr.prim.this "7.5.3 This")[.](#8.sentence-1)

[*Example [6](#example-6)*: class A {void f(A* p = this) { } // error}; â *end example*]

â *end note*]

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4475)

A default argument is evaluated each time the function is called
with no argument for the corresponding parameter[.](#9.sentence-1)

A parameter shall not appear as a potentially-evaluated expression
in a default argument[.](#9.sentence-2)

[*Note [6](#note-6)*:

Parameters of a function declared before a default argument
are in scope and can hide namespace and class member names[.](#9.sentence-3)

â *end note*]

[*Example [7](#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](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]") â *end example*]

A non-static member shall not be designated in a default argument unless

- [(9.1)](#9.1)

it is designated by
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access")),

- [(9.2)](#9.2)

it is designated by an expression
used to form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")), or

- [(9.3)](#9.3)

it appears as the operand of
a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") ([[expr.reflect]](expr.reflect "7.6.2.10 The reflection operator"))[.](#9.sentence-4)

[*Example [8](#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[.](#9.sentence-5)

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[.](#9.sentence-6)

Classes, objects, and members are described in [[class]](class "11 Classes")[.](#9.sentence-7)

â *end example*]

A default argument is not part of the
type of a function[.](#9.sentence-8)

[*Example [9](#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](#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]](over.match.viable "12.2.3 Viable functions"))[.](#9.sentence-9)

â *end note*]

[*Note [8](#note-8)*:

The candidate might have been found through a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") from which the declaration that provides the default argument is not reachable[.](#9.sentence-10)

â *end note*]

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4560)

A virtual function call ([[class.virtual]](class.virtual "11.7.3 Virtual functions")) uses the default
arguments in the declaration of the virtual function determined
by the static type of the pointer or reference denoting the
object[.](#10.sentence-1)

An overriding function in a derived class does not
acquire default arguments from the function it overrides[.](#10.sentence-2)

[*Example [10](#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*]

[77)](#footnote-77)[77)](#footnoteref-77)

This means that default
arguments cannot appear,
for example, in declarations of pointers to functions,
references to functions, ortypedef declarations[.](#footnote-77.sentence-1)
