Function definitions have the form
function-definition: attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
function-body: ctor-initializeropt compound-statement function-try-block = 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 ([class.mem]).
The declarator in a function-definition shall have the form
D1 ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt exception-specificationopt attribute-specifier-seqopt trailing-return-typeopt
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].
A cv-qualifier-seq or a ref-qualifier (or both) can be part of a non-static member function declaration, non-static member function definition, or pointer to member function only ([dcl.fct]); see [class.this].
[ 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.local]).
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.102
[ 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 ([global.names]). If a predefined variable is not odr-used ([basic.def.odr]), its string value need not be present in the program image.
A function definition of the form:
attribute-specifier-seqopt decl-specifier-seqopt declarator = 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 may be declared constexpr only if it would have been implicitly declared as constexpr, and may have an explicit exception-specification only if it is compatible ([except.spec]) with the exception-specification on the implicit declaration. If a function is explicitly defaulted on its first declaration,
it is implicitly considered to be constexpr if the implicit declaration would be,
it is implicitly considered to have the same exception-specification as if it had been implicitly declared ([except.spec]), and
in the case of a copy constructor, move constructor, copy assignment operator, or move assignment operator, it shall have the same parameter type as if it had been implicitly declared.
[ Example:
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() throw(int) = default; // ill-formed: exception specification does not match private: 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 special member 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 ]
[ Example:
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::nontrivial1() = default; // not first declaration
— end example ]
A function definition of the form:
attribute-specifier-seqopt decl-specifier-seqopt declarator = 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. — 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;
onlydouble(double);
};
— 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 inline. [ Note: The one-definition rule ([basic.def.odr]) 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. [ Example:
struct sometype {
sometype();
};
sometype::sometype() = delete; // ill-formed; not first declaration