Types, Values, and References¶
C++ types determine valid operations, representation requirements, overload selection, object lifetime rules, and generic constraints.
Fundamental and compound types¶
Fundamental types include Boolean, character, integer, floating-point, and
void. Exact widths are not universal for types such as int and long; use
fixed-width types such as std::int32_t only when the implementation provides
them and the exact width is part of the contract.
Compound types include arrays, functions, pointers, references, classes, enumerations, and pointer-to-member types.
int value = 42;
int* pointer = &value; // may be reseated; can be null
int& reference = value; // aliases value; must be initialized
int const& view = value; // read-only access through this reference
const restricts mutation through a particular access path; it does not prove
that no other alias can mutate the object. Logical constness may permit carefully
synchronized caches through mutable, but indiscriminate mutation violates
client expectations.
Value categories¶
Expressions have a type and a value category. The primary categories are:
- lvalue: identifies an object or function with persistent identity;
- xvalue: identifies an object whose resources may be reused;
- prvalue: computes a value used to initialize an object or operand.
These categories influence reference binding, overload resolution, temporary materialization, copying, and moving. “Everything is either on the stack or heap” is not the C++ object model.
Initialization¶
Brace initialization rejects many narrowing conversions. auto deduces a type
from the initializer; it does not make C++ dynamically typed. Check deduction
when references, top-level const, proxy types, or initializer lists matter.
Conversions¶
Implicit conversions can change sign, range, precision, or overload selection. Mixed signed/unsigned arithmetic is a frequent source of surprising comparisons. Prefer conversions that state intent and validate values before narrowing.
Named casts have distinct meanings:
static_castrequests a checked-at-compile-time language conversion;dynamic_castperforms supported runtime checks in polymorphic hierarchies;const_castchanges cv-qualification but cannot make a truly const object mutable;reinterpret_castperforms low-level reinterpretations with narrow valid uses.
Views and lifetime¶
std::span<T> views contiguous elements; std::string_view views character
data. Neither normally owns the referenced storage.
std::string_view invalid_view() {
std::string local{"temporary"};
return local; // dangling view after local is destroyed
}
Every non-owning view requires a lifetime argument: the referenced object must outlive every use of the view.
Exercises¶
- Explain the difference between
int const*,int* const, andint const* const. - Find the lifetime defect in a function returning a view of local storage.
- Explain why
autopreserves static typing.