as we’ve seen, a pointer is an object that can point to a different object. as a result, we can talk independently about whether a pointer is const and whether the objects to which it can point are const. we use the top-level const to indicate that the pointer itself is a const. when a pointer can point to a const object, we refer to that const as a low-level const.
more generally, top-level const indicates that an object itself is const. top-level const can appear in any object type,i.e., one of the built-in arithmetic types, a class type, or a pointer type. low-level const appears in the base type of compound types such as pointer or reference. note that pointer types, unlike most other type, can have both top-level and low-level const independently:
it is not uncommon to want to store the value of an expression in a variable. to declare the variable, we have to know the type of that expression. when we write a program, it can be surprisingly difficult–and sometimes even impossible–to determine the type of an expression. under the new standard, we can let the compiler figure out the type for us by using the auto type specifier. unlike type specifiers, such as double, that names a specifier type, auto tells the compiler to deduce the type from the initializer. by implication, a variable that uses auto as its type specifier must have initializer:
here the compiler will deduce the type of item from the type returned by applying + to val1 and val2.
first, as we’ve seen, when we use a reference, we are really using the object to which the reference refers. in particular, when we use a reference as in initializer, the initializer is the corresponding object. the compiler uses that object’s type for auto’s type deduction:
second, auto ordinarily ignores top-level consts. as usual in initializations, low-level consts, such as when an initializer is a pointer to const, are kept:
if we want the deduced type to have a top-level const, we must say so explicitly:
we can also specify that we want a reference to the auto-deduced type. normal initialization rules still apply:
when we ask for a reference to an auto-deduced type, top-level consts in the initializer are not ignored. as usual, consts are not top-level when we bind a reference to an initializer.
when we define several variables in the same statement, it is important to remember that a reference or pinter is part of a particular declarator and not part of the base type for the declaration. as usual, the initializers must provide consitent auto-deduced types:
sometimes we want to define a variable with a type that the compiler deduces from an expression but do not want to use that expression to initialize the variable. for such cases, the new standard introduced a second type specifier, decltype, which returns the type of its operand. the compiler analyzes the expression to determine its type but does not evaluate the expression:
here, the compiler does not call f, but it uses the type that such a call would return as the type for sum. that is, the compiler gives sum the same type as the type that would be returned if we were to call f.
the way decltype handles top-level const and references differs subtly from the way auto does. when the expression to which we apply decltype is a variable, decltype returns the type of that variable, including top-level const and references:
because cj is a reference, decltype(cj) is a reference type. like any other reference, z must be initialized.
it is worth nothing that decltype is the only context in which a variable defined as a reference is not treated as a synonym for the object to which it refers.
decltype and references
when we apply decltype to an expression that is not a variable, we get the type that expression yields.
here r is a reference, so decltype(r) is a reference type. if we want the type to which r refers, we can use r in an expression, such as r+0, which is an expression that yields a value that has a nonreference type.
on the other hand, the dereference operator is an example of an expression for which decltype returns a reference. as we’ve seen, when we dereference a pointer, we get the object to which the pointer points. moreover, we can assign to that object. thus, the type deduced by decltype(*p) is int&, not plain int.
another important difference between decltype and auto is that the deduction done by decltype depends on the form of its given expression. what can be confusing is that enclosing the name of variable in parentheses affects the type returned by decltype. when we apply decltype to a variable without any parentheses, we get the type of that variable. if we warp the variable’s name in one or more sets of parentheses, the compiler will evaluate the operand as an expression. a variable is an expression that can be the left-hand side of an assignment. as a result, decltype on such an expression yields a reference:
remember that decltype((variable))(note,double parentheses) is always a reference type, but decltype(variable) is reference type only if variable is a reference.
感謝您的通路,希望對您有所幫助。 歡迎大家關注、收藏以及評論。
我的更多部落格文章:nomasp部落格導讀
為使本文得到斧正和提問,轉載請注明出處:
http://blog.csdn.net/nomasp