[basic.def] (original) (raw)
6 Basics [basic]
6.2 Declarations and definitions [basic.def]
A declaration ([basic.pre]) may (re)introduce one or more names and/or entities into a translation unit.
If so, the declaration specifies the interpretation and semantic properties of these names.
A declaration of an entity X is a redeclaration of Xif another declaration of X is reachable from it ([module.reach]); otherwise, it is a first declaration.
Each entity declared by a declaration is also defined by that declaration unless:
- it declares a function without specifying the function's body ([dcl.fct.def]),
- it contains theextern specifier ([dcl.stc]) or alinkage-specification12 ([dcl.link]) and neither an initializer nor afunction-body,
- it declares a non-inline static data member in a class definition ([class.mem], [class.static]),
- it declares a static data member outside a class definition and the variable was defined within the class with the constexprspecifier ([class.static.data]) (this usage is deprecated; see [depr.static.constexpr]),
- it is an elaborated-type-specifier ([class.name]),
- it is anopaque-enum-declaration ([dcl.enum]),
- it is atemplate-parameter ([temp.param]),
- it is aparameter-declaration ([dcl.fct]) in a functiondeclarator that is not the declarator of afunction-definition,
- it is atypedef declaration ([dcl.typedef]),
- it is an alias-declaration ([dcl.typedef]),
- it is a namespace-alias-definition ([namespace.alias]),
- it is a using-declaration ([namespace.udecl]),
- it is a deduction-guide ([temp.deduct.guide]),
- it is a static_assert-declaration ([dcl.pre]),
- it is a consteval-block-declaration,
- it is anattribute-declaration ([dcl.pre]),
- it is anempty-declaration ([dcl.pre]),
- it is a using-directive ([namespace.udir]),
- it is a using-enum-declaration ([enum.udecl]),
- it is a template-declaration ([temp.pre]) whose template-head is not followed by either a concept-definition or a declarationthat defines a function, a class, a variable, or a static data member,
- it is an explicit instantiation declaration ([temp.explicit]), or
- it is an explicit specialization whosedeclaration is not a definition.
A declaration is said to be a definition of each entity that it defines.
[Example 1:
All but one of the following are definitions:int a; extern const int c = 1; int f(int x) { return x+a; } struct S { int a; int b; }; struct X { int x; static int y; X(): x(0) { } };int X::y = 1; enum { up, down }; namespace N { int d; }X anX; whereas these are just declarations:extern int a; extern const int c; int f(int); struct S; typedef int Int; namespace N1 = N; extern X anotherX; using N::d;
— _end example_]
[Example 2:
Given#include <string> struct C { std::string s; };int main() { C a; C b = a; b = a;} the implementation will implicitly define functions to make the definition of C equivalent tostruct C { std::string s; C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_caststd::string&&\(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_caststd::string&&\(x.s); return *this; } ~C() { } };
— _end example_]
In the definition of an object, the type of that object shall not be an incomplete type ([basic.types.general]), an abstract class type ([class.abstract]), or a (possibly multidimensional) array thereof.