C++11 the reference overlay rules and template parameter type deduction rules under the illustrated VS2013

Source: Internet
Author: User
Tags ibm developerworks

Background:
Recently in learning C++stl, out of chance, in the c++reference saw the vector under the Emplace_back function, do not want to cause a series of "exploration", so there is now this blog post.

Objective:
The Rvalue reference is undoubtedly a dazzling pearl in the new c++11 feature, based on which the mobile semantics and the perfect forwarding are realized, and the three are the "iron triangles" that make many C + + developers simply astounding (not all C + + developers, of course). In this "iron triangle", there is an unavoidable key detail, that is, reference overlay rules and template parameter type deduction rules. In fact, there is a good deal of information available on these two rules, but there is a characteristic--simple (in terms of form) that is difficult to understand (as far as it is understood), and there are no examples, just a brief explanation. And this article is precisely the details of the unfolding, giving a demonstration and proof. Admittedly, this is not a groundbreaking job, but it is also essential because it gives people a deeper and more thorough understanding of this critical detail, and in some ways fills the void.

"Illustrated" is because: there is a picture of the truth, at a glance, really true, indisputable.
"VS2013" is because: all the tests in this article and all from VS2013, considering the different compilation environment results may be slightly different, so for the sake of rigor, here added "VS2013".

Finally, say two points:
1. The form of this article (or in other words, logical order): The first conclusion, the second proof, when necessary to explain.

2. This article uses a lot of, so read it may have a sense of great length (but in fact the article logical structure clear, content at a glance), to the reader to bring the reader discomfort, please understand.

Resources:
1. wikipedia. Rvalue reference address: http://zh.wikipedia.org/wiki/%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8 (We strongly recommend that you see)
2. The Poly-Guest channel. [C + +] rvalue reference: Moving semantics with perfect forwarding dutor address: http://ju.outofmemory.cn/entry/105978
3. Blog Park. "original" C + + 11 perfect forwarding Hujian address: http://www.cnblogs.com/hujian/archive/2012/02/17/2355207.html
4.IBM developerworks.c++11 Standard new features: Rvalue reference and transfer semantics Li Shengli address: http://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/

Body:

Well, the book belongs to the body.
To make the problem clear, we first give the following function:

Template<typename t>void F (t&& fpar)//formal parameter parameter {    //function body}//call int a=1;int& apar=a;// Actual parameter real parameter F (APAR);

On this basis, the following table (set a as the basic type, such as int) is given:

Table 1

Description
1. In the preceding code, the invocation of the former parameter fpar the declared type is T&&, and the type of the argument Apar passed in when invoked is int&.
2. In the table above, the 2, 3, and 4 columns correspond to the reference overlay rules, and the 2, 3, and 5 columns correspond to the template parameter type deduction rules.
3. From the table above you can know:
The rule of the reference overlay rule is that there is one in Fpar and Apar before the call, and the result (that is, the actual type of Fpar after the call) is &; only if Fpar and Apar are &&, the result is &&.
The rule of derivation rules for template parameter types is that the actual type of T after the call is A& only if the Fpar is &&,apar is &, and the other 3 cases are a. (only on the table above, many of the information is not on this, the reason

In the red part is different, see note 4 below)
4. Take note of the red A in the table above, in the consulted data, that position is a&, but the result is a, which will be explained in detail later.
5. The template parameter type deduction discussed in this article is only for T in the above example, in c++11, the more classical type derivation includes auto,decltype and so on.

The following gives the verification and explanation:

1. Validation rules 1

Look at the picture:

Figure 1

In the program we set breakpoints to monitor variables, we see that the RA as the int& class argument call function Wai (because it is an outer function, here is simply named Wai, does not affect the description of the problem), after the call,t& w_a into int& w_a (that is, the actual type is an int &), and T W_aa is an int, that is, the type of T is the int type. Here, the actual type of the call to the post parameter w_a satisfies the reference overlay Rule 1 (in the table above).

There are two ways of understanding the reference overlay (as explained in the example above):

Way One:

When the parameter is passed,,t& and int& "effect", the result is int&, that is, t&+int&-int&. We regard it as a provision, without explanation. (The table above is given in this way)

Way two:

When the parameter is passed, the int& in front of the argument Ra is passed to T (will change T to int&), so,int& &-int& (note that there are spaces between the two ' & ' of int& &, not an rvalue reference), and will int& &

int& is considered a rule. Based on mode two, the above table will become (regardless of the type of T after the call):

Table 2

Where the 1th "Addend" is the content of the T, that is, the type before the argument, and the 2nd "Addend" is the reference form after T in the function parameter list, "and" is the actual form of the parameter after the function call. The correctness stipulated in the following illustration is as follows:

a& & a& a& && a& a& & & a& a&& &&-a&&

Both ways are possible. Just under the impression that the way the two go around a little bit, and that there is a T first becomes int& (as shown in Figure 1), and then become an int the sense of inexplicable. So, in the next recommended way one.

In the deduction of T, we use this method: First, the type of the formal parameter after the function call is obtained by the superposition principle, then the type is compared and matched with the type of the formal parameter in the function parameter list, and the type of T is obtained.

If a mismatch is found, then the overlay rule is used again to "deduce" the type of T (which we will encounter when validating Rule 3).

Take the case in Figure 1 as an example:

t& w_a (in the formal parameter list)

int& w_a (The actual type of the parameter after the function call, as determined by the overlay rule)

In contrast, T is of type int.

2. Validation rules 2

An illustration

Figure 2

This seems to have verified rule 2, but see:

Figure 3

I wonder if anyone would be surprised that a is an rvalue reference, why would I call void F (int&)? In other words, when a is a left value?

Now, to tell you a conclusion (believe that many people know it, just repeat it):

The C + + standard specifies that a named Rvalue reference is treated as a left-hand value. [Note 6] The implication of this provision is that an rvalue reference would have been used to implement the move semantics, thus requiring the memory address of an object to be bound, and then having permission to modify the content of that object, which is exactly the same as an lvalue binding. The difference between an rvalue binding and an lvalue binding is in determining the resolution of a function overload. For the move constructor member function and the move Assignment operator member function, the shape and the real parameters are combined with the rvalue reference, and in these two member function bodies, because the formal parameters are all named and therefore are treated as lvalue, this parameter can be used to modify the internal state of the incoming object. In addition, rvalue reference as Xvalue (deathbed value) would have been used for moving semantics to empty its contents at once. A named makes it a more durable lifetime, which is dangerous, and therefore provides an lvalue reference after it is named, unless the program explicitly specifies that its type is cast to an rvalue reference.
--Wikipedia address: http://zh.wikipedia.org/wiki/%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8

In addition, it can be seen that the difference between,&& and & can be used as an overloaded flag.

Now, I believe we are no longer surprised. Looking back at Figure 2, we understand that this validation is not valid and that the RA is treated as an lvalue, equivalent to or in validation rule 1. So, what do we do? See:

Figure 4

Although the conclusion has not changed, the verification method is effective.

The reader can add the two F functions in Figure 3, and then write F (RT ()) in the main function, based on the figure 4 Code, and get the output "right value: 1". In order to shorten the length of the article, it is not here, please verify it.

For the code in Figure 4, the following points are stated:

1. As mentioned earlier, a named Rvalue reference is handled by an lvalue reference, so to achieve the experimental purpose, the named Rvalue reference cannot be passed to the function wai (), so we pass an unnamed rvalue reference such as the function return value.

2. If we return a local variable or a reference to a temporary object (such as an int a=1;return a++ in the RT () function, even if the int is a=1, it is not possible to do so, because a++ is a copy of a before + +, which belongs to the temporary object), The result is not correct (output 1 is not obtained). (The reason is not clear for the moment, it may be that the code behind the execution of the temporary variable space overwrite (rewrite), in the next disassembly single-step also did not find the exact answer (the next compilation is not good), here please have to know the reason of Daniel give advice, under the gratitude, first thanked)

3. As you can see in Figure 4, the RT () function must convert the global variable a coercion type to the int&& type and return it, otherwise, if it is written as return a, the compiler will produce an error similar to "cannot bind rvalue reference to left value". The reason is that a named Rvalue reference A is treated as a left-hand value.

A const in 4.void Wai (const t& w_a) cannot be saved because a very-reference (t&) cannot accept an rvalue reference.

The const in 5.void nei (const int& n_a) cannot be saved, as you can see in Figure 4, when Nei (w_a) is executed in Wai (), and W_a is a const int& type.

Simply say the derivation of T:

Const t& W_a (in the argument list)

Const int& W_A (actual type after function call w_a)

In contrast, T is of type int.

At this point, we can make sure that the red a in table 1 is the correct,a& to say wrong.

3. Validation rules 3

An illustration

Here's just a deduction for T. As follows:

t&& w_a (type of w_a in the argument list)

int& W_a (actual type after function call w_a)

Obviously, this cannot be matched directly at this time. Here we use Table 2 (the reason for table 2, because table 2 is more intuitive than table 1) in the 2nd a& + &&, A&, the introduction of T is the int& type.

4. Validation rules 4

An illustration

First of all, here we said that the very value of lvalue reference cannot accept rvalue references, in, void Nei (int& n_a), w_a for int&& type, then the NEI (W_A) in RT ();

Do not forget that although w_a is shown as the int&& type, it is a named rvalue reference, so as lvalue reference processing, nature can pass. If we change void nei (int& n_a) to void Nei (int&& n_a), it cannot be passed (W_a is not accepted int& as,int&& type int&), Readers can try them on their own.

Again, the derivation of T:

t&& w_a (type of w_a in the argument list)

int&& w_a (the actual type of w_a after a function call, regardless of c++11 treats it as int&)

In contrast, T is int type.

At this point, 4 reference overlay rules and the corresponding template parameter type deduction are all finished, thank you!

Postscript:

In the next Love study, HI Inquiry, seeking truth from facts, but on the other hand, and really caishuxueqian, limited capacity, so can only do some basic work. But even so, there are inevitably omissions and even mistakes, here, in

I implore everyone to criticize and advise. Your criticism is the source of continuous progress!

C++11 the reference overlay rules and template parameter type deduction rules under the illustrated VS2013

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.