Primary expressions are the building blocks of more complex expressions. They are literals, names, and names qualified by the scope-resolution operator (::).
primary-expression:
literal
this
::identifier
::operator-function-name
::qualified-name
(expression )
name
A literal is a constant primary expression. Its type depends on the form of its specification. See “Literals” in Chapter 1, on topic for complete information about specifying literals.
The this keyword is a pointer to a class object. It is available within nonstatic member functions and points to the instance of the class for which the function was invoked. The this keyword cannot be used outside the body of a class-member function.
The type of the this pointer is type *const (where type is the class name) within functions not specifically modifying the this pointer. The following example shows member function declarations and the types of this:
class Example
{
public:
void Func(); // Example: * const this
void Func() const; // Example: const * const this
void Func() volatile; // Example: volatile * const this
};
See “Type of this Pointer” in Chapter 8, on topic for more information about modifying the type of the this pointer.
The this pointer has an associated addressing model—from the compilation options, the “ambient data model” of the class, or one that is explicitly specified in the declaration of an object of class type. Therefore, the this pointer can be a near, far, or huge pointer. For more information about addressing models as they affect classes, see “Memory-Model Modifiers and Member Functions” in Appendix B, on topic .¨
The scope-resolution operator (::), followed by an identifier, operator-function-name, or qualified-name constitutes a primary expression. The type of this expression is determined by the declaration of the identifier, operator-function-name, or name. It is an l-value if the declaring name is an l-value. The scope-resolution operator allows a global name to be referred to, even if that name is hidden in the current scope. See “Scope” in Chapter 2, on topic for an example of how to use the scope-resolution operator.
An expression enclosed in parentheses is a primary expression whose type and value are identical to those of the unparenthesized expression. It is an l-value if the unparenthesized expression is an l-value.
A name is a primary expression that can appear only after the member-selection operators (. or –>).
name:
identifier
operator-function-name
conversion-function-name
~class-name
qualified-name
Any identifier that has been declared is a name.
An operator-function-name is a name that is declared in the form:
operator operator-name( argument 1[[, argument 2]] );
See “Overloaded Operators” in Chapter 12, on topic for more information about declaration of operator-function-name.
A conversion-function-name is a name that is declared in the form:
operator type-name()
Note:
You can supply a derivative type name, such as char * in place of the type-name when declaring a conversion function.
Conversion functions supply conversions to and from user-defined types. For more information about user-supplied conversions, see “Conversion Functions” in Chapter 11, on topic .
A name declared as ~ class-name is taken as the “destructor” for objects of a class type. Destructors typically perform cleanup operations at the end of an object's lifetime. Destructors are discussed in-depth in “Destructors” in Chapter 11, on topic .
qualified-name:
qualified-class-name::name
If a qualified-class-name is followed by the scope-resolution operator (::), and then the name of a member of either that class or a base of that class, then the scope-resolution operator is considered a qualified-name. The type of a qualified-name is the same as the type of the member, and the result of a qualified-name expression is the member. If the member is an l-value, then the qualified-name is also an l-value. For information about declaring qualified-class-name, see “Type Specifiers” in Chapter 6, on topic or “Class Names” in Chapter 8, on topic .
The class-name part of a qualified-class-name can be hidden by redeclaration of the same name in the current or enclosing scope; the class-name is still found and used. See “Scope” in Chapter 2, on topic for an example of how to use a qualified-class-name to access a hidden class-name.
Note:
Class constructors and destructors of the form class-name :: class-name, and class-name :: ~ class-name, respectively, must refer to the same class-name.
A multiply-qualified name, such as the following, designates a member of a nested class:
class-name :: class-name :: name