6 Basic concepts [basic]

6.1 Declarations and definitions [basic.def]

A declaration может ввести одно или несколько имен в единицу перевода или повторно объявить имена, введенные предыдущими объявлениями. Если это так, в объявлении указываются интерпретация и атрибуты этих имен. Объявление также может иметь следующие последствия:

Декларация - это definition если

[ Example: Все, кроме одного из следующих определений:

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

тогда как это просто объявления:

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]

[ В некоторых случаях реализации C ++ неявно определяют , , , , , или функции - члены. ] [ УчитываяNote: default constructorcopy constructormove constructorcopy assignment operatormove assignment operator destructor end noteExample:

#include <string>

struct C {
  std::string s;    // std​::​string is the standard library class (Clause [strings])
};

int main() {
  C a;
  C b = a;
  b = a;
}

реализация будет неявно определять функции, чтобы сделать определение C эквивалентным

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: Имя класса также может быть неявно объявлено с помощью elaborated-type-specifier. ]end note

Программа плохо сформирована, если определение любого объекта дает объекту значение incomplete type.

Появившись внутри приготовился корпусе declaration-seqв linkage-specificationне влияет на заявление , является ли определение.