Compound types can be constructed in the following ways:
arrays of objects of a given type, [dcl.array];
functions, which have parameters of given types and return void or references or objects of a given type, [dcl.fct];
pointers to void or objects or functions (including static members of classes) of a given type, [dcl.ptr];
references to objects or functions of a given type, [dcl.ref]. There are two types of references:
classes containing a sequence of objects of various types (Clause [class]), a set of types, enumerations and functions for manipulating these objects ([class.mfct]), and a set of restrictions on the access to these entities (Clause [class.access]);
unions, which are classes capable of containing objects of different types at different times, [class.union];
enumerations, which comprise a set of named constant values. Each distinct enumeration constitutes a different enumerated type, [dcl.enum];
pointers to non-static 50 class members, which identify members of a given type within objects of a given class, [dcl.mptr].
These methods of constructing types can be applied recursively; restrictions are mentioned in [dcl.ptr], [dcl.array], [dcl.fct], and [dcl.ref].
The type of a pointer to void or a pointer to an object type is called an object pointer type. [ Note: A pointer to void does not have a pointer-to-object type, however, because void is not an object type. — end note ] The type of a pointer that can designate a function is called a function pointer type. A pointer to objects of type T is referred to as a “pointer to T.” [ Example: a pointer to an object of type int is referred to as “pointer to int ” and a pointer to an object of class X is called a “pointer to X.” — end example ] Except for pointers to static members, text referring to “pointers” does not apply to pointers to members. Pointers to incomplete types are allowed although there are restrictions on what can be done with them ([basic.align]). A valid value of an object pointer type represents either the address of a byte in memory ([intro.memory]) or a null pointer ([conv.ptr]). If an object of type T is located at an address A, a pointer of type cv T* whose value is the address A is said to point to that object, regardless of how the value was obtained. [ Note: For instance, the address one past the end of an array ([expr.add]) would be considered to point to an unrelated object of the array's element type that might be located at that address. There are further restrictions on pointers to objects with dynamic storage duration; see [basic.stc.dynamic.safety]. — end note ] The value representation of pointer types is implementation-defined. Pointers to cv-qualified and cv-unqualified versions ([basic.type.qualifier]) of layout-compatible types shall have the same value representation and alignment requirements ([basic.align]). [ Note: Pointers to over-aligned types ([basic.align]) have no special representation, but their range of valid values is restricted by the extended alignment requirement. This International Standard specifies only two ways of obtaining such a pointer: taking the address of a valid object with an over-aligned type, and using one of the runtime pointer alignment functions. An implementation may provide other means of obtaining a valid pointer value for an over-aligned type. — end note ]
A pointer to cv-qualified ([basic.type.qualifier]) or cv-unqualified void can be used to point to objects of unknown type. Such a pointer shall be able to hold any object pointer. An object of type cv void* shall have the same representation and alignment requirements as cv char*.
Static class members are objects or functions, and pointers to them are ordinary pointers to objects or functions.