11 Declarators [dcl.decl]

11.4 Function definitions [dcl.fct.def]

11.4.1 In general [dcl.fct.def.general]

Function definitions have the form

	attribute-specifier-seq decl-specifier-seq declarator virt-specifier-seq function-body
	ctor-initializer compound-statement
	= default ;
	= delete ;

Any informal reference to the body of a function should be interpreted as a reference to the non-terminal function-body. The optional attribute-specifier-seq in a function-definition appertains to the function. A virt-specifier-seq can be part of a function-definition only if it is a member-declaration.

In a function-definition, either void declarator ; or declarator ; shall be a well-formed function declaration as described in [dcl.fct]. A function shall be defined only in namespace or class scope.

[Example: A simple example of a complete function definition is

int max(int a, int b, int c) {
  int m = (a > b) ? a : b;
  return (m > c) ? m : c;

Here int is the decl-specifier-seq; max(int a, int b, int c) is the declarator; { /* ... */ } is the function-body. end example]

A ctor-initializer is used only in a constructor; see [class.ctor] and [class.init].

[Note: A cv-qualifier-seq affects the type of this in the body of a member function; see [dcl.ref]. end note]

[Note: Unused parameters need not be named. For example,

void print(int a, int) {
  std::printf("a = %d\n",a);

end note]

In the function-body, a function-local predefined variable denotes a block-scope object of static storage duration that is implicitly defined (see [basic.scope.block]).

The function-local predefined variable _­_­func_­_­ is defined as if a definition of the form

static const char __func__[] = "function-name";

had been provided, where function-name is an implementation-defined string. It is unspecified whether such a variable has an address distinct from that of any other object in the program.103 [Example:

struct S {
  S() : s(__func__) { }             // OK
  const char* s;
void f(const char* s = __func__);   // error: _­_­func_­_­ is undeclared

end example]

Implementations are permitted to provide additional predefined variables with names that are reserved to the implementation. If a predefined variable is not odr-used, its string value need not be present in the program image.

11.4.2 Explicitly-defaulted functions [dcl.fct.def.default]

A function definition of the form:

attribute-specifier-seq decl-specifier-seq declarator virt-specifier-seq  = default ;

is called an explicitly-defaulted definition. A function that is explicitly defaulted shall

  • be a special member function,

  • have the same declared function type (except for possibly differing ref-qualifiers and except that in the case of a copy constructor or copy assignment operator, the parameter type may be “reference to non-const T”, where T is the name of the member function's class) as if it had been implicitly declared, and

  • not have default arguments.

An explicitly-defaulted function that is not defined as deleted may be declared constexpr only if it would have been implicitly declared as constexpr. If a function is explicitly defaulted on its first declaration, it is implicitly considered to be constexpr if the implicit declaration would be.

If a function that is explicitly defaulted is declared with a noexcept-specifier that does not produce the same exception specification as the implicit declaration ([except.spec]), then

  • if the function is explicitly defaulted on its first declaration, it is defined as deleted;

  • otherwise, the program is ill-formed.


struct S {
  constexpr S() = default;              // ill-formed: implicit S() is not constexpr
  S(int a = 0) = default;               // ill-formed: default argument
  void operator=(const S&) = default;   // ill-formed: non-matching return type
  ~S() noexcept(false) = default;       // deleted: exception specification does not match
  int i;
  S(S&);                                // OK: private copy constructor
S::S(S&) = default;                     // OK: defines copy constructor

end example]

Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy]), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base.end note]


struct trivial {
  trivial() = default;
  trivial(const trivial&) = default;
  trivial(trivial&&) = default;
  trivial& operator=(const trivial&) = default;
  trivial& operator=(trivial&&) = default;
  ~trivial() = default;

struct nontrivial1 {
nontrivial1::nontrivial1() = default;   // not first declaration

end example]

11.4.3 Deleted definitions [dcl.fct.def.delete]

A function definition of the form:

attribute-specifier-seq decl-specifier-seq declarator virt-specifier-seq  = delete ;

is called a deleted definition. A function with a deleted definition is also called a deleted function.

A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed. [Note: This includes calling the function implicitly or explicitly and forming a pointer or pointer-to-member to the function. It applies even for references in expressions that are not potentially-evaluated. If a function is overloaded, it is referenced only if the function is selected by overload resolution. The implicit odr-use of a virtual function does not, by itself, constitute a reference. end note]

[Example: One can enforce non-default-initialization and non-integral initialization with

struct onlydouble {
  onlydouble() = delete;                // OK, but redundant
  onlydouble(std::intmax_t) = delete;

end example]

[Example: One can prevent use of a class in certain new-expressions by using deleted definitions of a user-declared operator new for that class.

struct sometype {
  void* operator new(std::size_t) = delete;
  void* operator new[](std::size_t) = delete;
sometype* p = new sometype;     // error, deleted class operator new
sometype* q = new sometype[3];  // error, deleted class operator new[]

end example]

[Example: One can make a class uncopyable, i.e. move-only, by using deleted definitions of the copy constructor and copy assignment operator, and then providing defaulted definitions of the move constructor and move assignment operator.

struct moveonly {
  moveonly() = default;
  moveonly(const moveonly&) = delete;
  moveonly(moveonly&&) = default;
  moveonly& operator=(const moveonly&) = delete;
  moveonly& operator=(moveonly&&) = default;
  ~moveonly() = default;
moveonly* p;
moveonly q(*p);                 // error, deleted copy constructor

end example]

A deleted function is implicitly an inline function. [Note: The one-definition rule applies to deleted definitions. end note] A deleted definition of a function shall be the first declaration of the function or, for an explicit specialization of a function template, the first declaration of that specialization. An implicitly declared allocation or deallocation function ([basic.stc.dynamic]) shall not be defined as deleted. [Example:

struct sometype {
sometype::sometype() = delete;  // ill-formed; not first declaration

end example]