6 Basics [basic]

6.2 Declarations and definitions [basic.def]

A declaration 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 or typedef-name X is a redeclaration of X if another declaration of X is reachable from it ([module.reach]).
A declaration may also have effects including:
Each entity declared by a declaration is also defined by that declaration unless:
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; // defines a extern const int c = 1; // defines c int f(int x) { return x+a; } // defines f and defines x struct S { int a; int b; }; // defines S, S​::​a, and S​::​b struct X { // defines X int x; // defines non-static data member x static int y; // declares static data member y X(): x(0) { } // defines a constructor of X }; int X::y = 1; // defines X​::​y enum { up, down }; // defines up and down namespace N { int d; } // defines N and N​::​d namespace N1 = N; // defines N1 X anX; // defines anX whereas these are just declarations: extern int a; // declares a extern const int c; // declares c int f(int); // declares f struct S; // declares S typedef int Int; // declares Int extern X anotherX; // declares anotherX using N::d; // declares d
— end example]
[Note 1: 
In some circumstances, C++ implementations implicitly define the default constructor ([class.default.ctor]), copy constructor, move constructor ([class.copy.ctor]), copy assignment operator, move assignment operator ([class.copy.assign]), or destructor member functions.
— end note]
[Example 2: 
Given #include <string> struct C { std::string s; // std​::​string is the standard library class ([string.classes]) }; int main() { C a; C b = a; b = a; } the implementation will implicitly define functions to make the definition of C equivalent to struct C { std::string s; C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast<std::string&&>(x.s)) { } // : s(std​::​move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast<std::string&&>(x.s); return *this; } // { s = std​::​move(x.s); return *this; } ~C() { } };
— end example]
[Note 2: 
A class name can also be implicitly declared by an elaborated-type-specifier ([dcl.type.elab]).
— end note]
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.
16)16)
Appearing inside the brace-enclosed declaration-seq in a linkage-specification does not affect whether a declaration is a definition.