Objective Modern C ++ Reading Notes Item 1 Understanding template type derivation, objective tivemodernc
Recently, I found the book "objective Modern C ++". The author is Scott Meyers, the famous C ++ and STL.
Just as C ++ 11 gradually became popular, and even the new features of C ++ 14 came into the eyes of everyone, the book "impulsive Modern C ++" came into being. This book, like its predecessors, is based on dozens of terms, but this time it focuses on the new features of C ++ 11 and C ++ 14.Auto,Decltype, Move, lambda expressions ...... What are the details and key points behind these strong and powerful new features ?......
When I was reading this book, I felt the pleasure of opening up and reading some of Scott's previous books when I was a beginner in C ++. Then I tried to extract one or two pieces of data, make some records based on my thoughts, and check some of my knowledge points. I hope you can correct them more.
Note:
Clams
BytesBytesBytesBytesFragments in such a boxNot from the original bookBut my own understanding.
Item 1 Understand template type deduction-Understanding template type Derivation
Template type derivation has long been a feature of C ++. For example:
Template <typename T> void f (ParamType param); f (expr );//CallF
WhereParamTypeYes andTThe related types only contain some modifiers, suchConstOr reference modifier ). For example:
Template <typename T> void f (const T & param); // ParamTypeIsConst T &
For such a call:
int x = 0;f(x);
A Specialize function is generated by type derivation,TDeduce isInt,ParamTypeIs deducedConst int &.
The above process is type derivation, and
template<> void f<int>(int);
It is not a type derivation-because there is no "type Derivation", it is directly specified-cppreference to call this instantiate and instantiate. The compiler will feature function templates with specific template parameters.
In this form,TThe Derivation not only depends onExprAndParamTypeForm. There are three situations in this book:
Scenario 1:
ParamTypeIs a pointer or reference type, but not a universal reference)
(At this time, the book does not detail what is a universal reference, but it has little impact on this situation, because the universal reference is not a reference of the Left value, that is, it is not likeInt &, T &)
In the first case, the Type derivation rules are as follows:
In the first two,ExprIt refers to the real parameter (argument) of the function, andParamTypeIs the type of the parameter. Example:
template<typename T>void f(T& param);int x = 27;const int cx = x;const int& rx = x;f(x); // T -> int, ParamType -> int&f(cx); // T -> const int, ParamType -> const int&f(rx); // T -> const int, ParamType -> const int&
Expr, That is,X, cx, rxAfter removing the reference partInt, const int, AndParamWe will reference these types of variables,ParamTypeThe above results are exported.
Important:
WhenConstWhen an object to a referenced parameter (parameter), the caller wants this object to be retainedConstFeature, that is, immutability.
Template type derivation follows this key point. Therefore, transferConstObject To template parametersT &It is safe and will not be lostConstAttribute.
The above rules are also true for right-value reference.
In the preceding exampleParamTypeChangeConst T &In the preceding exampleParamTypeDeducedConst int &,TThenInt. BecauseParamTypeIn the formConst, After matchingTYou do not need to includeConst.
ForParamTypeIs a pointer, and the derivation process is the same. Only remove the "ignore reference part" step, and only perform pattern matching on the pointer type.
Case 2:
ParamTypeIs a universal reference
When the parameter of the template function is referenced by the universal, for example, "like" rvalue reference, that isT &&This type, whereTTemplate type parameter.
I think, for the so-called universal reference, refer to the "reference overlay effect" table first:
&-> &
&-> &
&-> &
&-> &&
I think this may be done: & Reference & reference is & reference, & reference is & reference ......
In my understanding, any of the referenced & references are prototype, so it is called a universal reference. Because it is superimposed on undetermined template type T, although the writing method is the same, it is not a reference to the right value, because the right value reference applies to a specific type.
Reference http://stackoverflow.com/questions/20364297/why-universal-references-have-the-same-syntax-as-rvalue-references
For universal reference, the type deduction rule is:
Rule 1 can reference the overlay table,ExprThe type is-> the right of the number. If it is a left value, that is, "&", only the left value can be changed through the universal reference &. Even ifParamTypeIt is declared in a similar form as the right value reference,ParamTypeIt is also deduced as a reference of the Left value.
I think this derivation is due to the undeterminedParamTypeDoes not indicate a reference type for the right value, but can only be used as a type with an unknown numberT. For exampleTIfInt &&, ThenT &YesInt &.
The example of case 2 in the book is:
template<typename T>void f(T&& param); // param is now a universal reference
int x = 27; const int cx = x; const int& rx = x;
f(x); // x -> lvalue, T -> int&, ParamType -> int&f(cx); // cx -> lvalue, T -> const int&, ParamType -> const int&f(rx); // rx -> lvalue, T -> const int&, ParamType -> const int&f(27); // 27 -> rvalue, T -> int, ParamType -> int&&
4th calls are returned in Case 1 rule.ExprIs a right value, and is boundInt &&, WhereTIsInt.
Case 3:
ParamTypeNeither pointer nor reference
Like this, pass by value/by copy (pass-by-value ):
template<typename T>void f(T param);
SoParamAlways copy the real parameter (argument. In this case, there are rules:
int x = 27; const int cx = x; const int& rx = x;
f(x); // T and ParamTypes -> intf(cx); // T and ParamTypes -> intf(rx); // T and ParamTypes -> int
BecauseParamAlwaysExprSo it will not affectExpr, SoExprOfConst,VolatileAndParamNo.
This is also in line with the above, the caller wants to pass in the original characteristics of the object (suchConst) Will not be affected, the implementation of the program must follow this hope.
Here is an original bookConst char * constThe example of transferring by copy (passing by value-relative to transferring by reference) is not detailed.
Array as real Parameter
C/C ++ has such a feature, that is, the degradation of arrays (decay ):
Const char str [] = "hello"; // const char [6] const char * p = str ;//Array degrades to pointer
ObviouslyStrAndPThe types are different. In addition, for the syntax in C, the function parameters can be declared as arrays, but the following two are the same:
void func(char str[]);void func(char *str);
This is because the parameter in array form is processed as a pointer.
Therefore, for the template parameters passed by valueTFor example, real parameters are arrays.Char [],TDeducedChar *. (It can be considered that the degradation of the array first occurs .)
However, when the template parameter is referenced, it can be "true" to reference the passed array (that is, no array degradation occurs ):
template<typename T>void f(T& param);f(str); // T -> const char[6], ParamType -> const char (&)[6]
In an example, the size of the array is obtained through the template during the compilation period (the temporarily unrelated part of the code is removed ):
template<typename T, std::size_t N>constexpr std::size_t arraySize(T (&)[N]) { return N;}
Function as real Parameter
In addition to arrays, functions are returned as pointers. However, you can also provide reference type parameters in the template to avoid degradation:
void someFunc(int, double); // someFunc -> void(int, double)
template<typename T>void f1(T param);
template<typename T>void f2(T& param);
f1(someFunc); // ParamType -> void (*)(int, double)f2(someFunc); // ParamType -> void (&)(int, double)
Arrays and functions are degraded based on their identifiers.
Note