it declares a static data member outside a class definition
and the variable was defined within the class with the constexpr
specifier (this usage is deprecated; see [depr.static.constexpr]),
All but one of the following are definitions:
int a; // defines aexternconstint c =1; // defines cint f(int x){return x+a; }// defines f and defines xstruct S {int a; int b; }; // defines S, S::a, and S::bstruct X {// defines Xint x; // defines non-static data member xstaticint y; // declares static data member y
X(): x(0){}// defines a constructor of X};
int X::y =1; // defines X::yenum{ up, down }; // defines up and downnamespace N {int d; }// defines N and N::dnamespace N1 = N; // defines N1
X anX; // defines anX
whereas these are just declarations:
externint a; // declares aexternconstint c; // declares cint f(int); // declares fstruct S; // declares Stypedefint Int; // declares Intextern X anotherX; // declares anotherXusing N::d; // declares d
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.
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(){}};
In the definition of an object,
the type of that object shall not be
an incomplete type ([basic.types]),
an abstract class type, or
a (possibly multi-dimensional) array thereof.