int i = 42; const int &r1 = i; // we can bind a const int& to a plain int object const int &r2 = 42; // ok: r1 is a reference to const const int &r3 = r1 * 2; // ok: r3 is a reference to const int &r4 = r1 * 2; // error: r4 is a plain, non const reference double dval = 3.14; const int &ri = dval; 《==》 const int temp = dval; // create a temporary const int from the double const int &ri = temp; // bind ri to that temporary20、 Pointers and const
const double pi = 3.14; // pi is const; its value may not be changed double *ptr = π // error: ptr is a plain pointer const double *cptr = π // ok: cptr may point to a double that is const *cptr = 42; // error: cannot assign to *cptr double dval = 3.14; // dval is a double; its value can be changed cptr = &dval; // ok: but can't change dval through cptr21、A constant expression is anexpression whose value cannot change and that can be eva luated at compile time.A literal is a constant expression. A const object that is initialized from aconstant expression is also a constant expression.
const int max_files = 20; // max_files is a constant expression const int limit = max_files + 1; // limit is a constant expression int staff_size = 27; // staff_size is not a constant expression const int sz = get_size(); // sz is not a constant expression
Under the new standard, we can ask the compiler to verify that avariable is a constant expression by declaring the variable in a constexprdeclaration. Variables declared as constexpr are implicitly const and must beinitialized by constant expressions:
constexpr int mf = 20; // 20 is a constant expression constexpr int limit = mf + 1; // mf + 1 is a constant expression constexpr int sz = size(); // ok only if size is a constexpr function
Generally, it isa good idea to use constexpr for variables that you intend to use as constantexpressions.
22、A type alias is a name that is a synonym for another type.We candefine a type alias in one of two ways. Traditionally, we use a typedef:
typedef double wages; // wages is a synonym for double typedef wages base, *p; // base is a synonym for double, pfor double*
The new standard introduced a second way to define a typealias, via an alias declaration:
using SI = Sales_item; // SI is a synonym for Sales_item23、 Pointers, const, and Type Aliases
typedef char *pstring; const pstring cstr = 0; // cstr is a constant pointer to char const pstring *ps; // ps is a pointer to a constant pointer to char24
auto i = 0, *p = &i; // ok: i is int and p is a pointer to int auto sz = 0, pi = 3.14; // error: inconsistent types for sz and pi int i = 0, &r = i; auto a = r; // a is an int (r is an alias for i, which has type int) const int ci = i, &cr = ci; auto b = ci; // b is an int (top-level const in ci is dropped) auto c = cr; // c is an int (cr is an alias for ci whose const is top-level) auto d = &i; // d is an int*(& of an int object is int*) auto e = &ci; // e is const int*(& of a const object is low-level const) const auto f = ci; // deduced type of ci is int; f has type const int auto &g = ci; // g is a const int& that is bound to ci auto &h = 42; // error: we can't bind a plain reference to a literal const auto &j = 42; // ok: we can bind a const reference to a literal auto k = ci, &l = i; // k is int; l is int& auto &m = ci, *p = &ci; // m is a const int&;p is a pointer to const int // error: type deduced from i is int; type deduced from &ci is const int auto &n = i, *p2 = &ci;
25、etimes we want to define avariable with a type that the compiler deduces from an expression but do notwant to use that expression to initialize the variable. For such