Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Citation overlay rules and template parameter type derivation rules under VS2013 are illustrated in figure 11.

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

Background:

Recently, when I was studying C++STL, I accidentally saw the emplace_back function under vector on C++Reference. I didn't want to trigger a series of "explorations", so I have this blog post.

Foreword:

Right-value reference is undoubtedly a dazzling pearl in the new features of Candles11, based on which mobile semantics and perfect forwarding are realized, which constitute the "iron triangle" that many C++ developers admire (not all C++ developers, of course). In this "iron triangle", there is a key detail that can not be avoided, that is to quote superposition rules and template parameter type derivation rules. In fact, a lot of information can be found about these two rules, but they both have one characteristic-simple (in terms of form) and difficult to understand (in terms of understanding) (at least in my opinion), and there are no examples, just a brief account. The purpose of this paper is to expand this detail and give a demonstration and proof. Admittedly, this is not groundbreaking work, but I think it is also essential, because it allows people to understand this key detail more deeply and thoroughly, and, in a way, fills the gap.

The reason for the "picture theory" is that there is a picture and the truth, which is clear at a glance, authentic and irrefutable.

"under VS2013" is because: all the tests and screenshots in this article are from VS2013, considering that the results may be slightly different in different compilation environments, so, for the sake of rigor, "under VS2013" is added here.

Finally, I would like to make two more points:

1. The writing form of this article (it can also be said to be a logical order): first come to a conclusion, then prove it, and explain it if necessary.

two。 This article uses a large number of screenshots, so there may be a sense of a lot of text to read (but in fact, the logical structure of the article is clear, the content is clear at a glance). Please forgive me for the discomfort caused to the reader.

Reference:

1. Wikipedia. Right value reference address: http://zh.wikipedia.org/wiki/%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8 (strongly recommended)

two。 Guest gathering Channel. [C++] right reference: mobile semantics and perfect forwarding author: Dutor address: http://ju.outofmemory.cn/entry/105978

3. Blog Garden. C++ 11 perfect retweet author: Hujian address: http://www.cnblogs.com/hujian/archive/2012/02/17/2355207.html

New feature of 4.IBM developerWorks.C++11 standard: right value reference and transfer semantics author: Li Shengli address: http://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/

Text:

All right, the book is in the text.

To clarify the problem, let's first give the following functions:

Templatevoid f (apar=a;//actual parameter & fpar) / / formal parameter parameter {/ / function body} / / call int aplom1bot int & apar=a;//actual parameter argument f (apar)

On this basis, the following table is given (let A be the basic type, such as int):

Table 1

Description:

1. In the previous code, the type of the parameter fpar before the call is declared to be called, and the type of the argument apar passed in when the call is called is int&.

two。 In the above table, columns 2, 3 and 4 correspond to reference overlay rules, and columns 2, 3 and 5 correspond to template parameter type derivation rules.

3. As can be seen from the above table:

The rule of citing the overlay rule is that one of the fpar and apar before the call is &, and the result (that is, the actual type of fpar after the call) is &; only if both fpar and apar are & &.

The rule of template parameter type derivation is that only when fpar is & & and apar is & before calling, the actual type of T after call is A, and in the other three cases it is A. (just the above table, whether a lot of information is like this, the reason

The red part is different, see note 4 below)

4. Notice the red An in the table above. In the checked data, that location is A, but the result below is A, which will be explained in detail later.

5. The template parameter type derivation discussed in this paper is only for T in the above example. In Clover 11, the more classical type derivation includes auto,decltype and so on.

The following verification and explanation are given one by one:

1. Validation rule 1

Look at the picture:

Figure 1

In the program, we set a breakpoint to monitor variables, and we see that ra calls the function wai as an argument of the int& class (because it is an outer function, it is simply named wai here, which does not affect the description). After the call, T & w_aa becomes an int (that is, the actual type becomes int&), while T w_aa becomes an int, that is, the type of T is int. Here, the actual type of the invocation parameter witera satisfies the reference overlay rule 1 (in the above table).

With regard to reference superposition, there are two ways to understand it (the above example is an example):

Method 1:

When the parameter is passed, T & "acts" with int&, and the result is int&, that is, Tunable intact &-> int&. We regard it as a rule and there is no need to explain it. (the above table is given in this way.)

Method 2:

When the parameter is passed, the int& in front of the argument ra is passed to T (that is, T is replaced by int&), so int& &-> int& (note that there is a space between the two'&'of int& &, not a right value reference), and int& &->

Int& is treated as a rule. Based on mode 2, the above table will become (regardless of the type of T after the call):

Table 2

Among them, the first "addition" is the content of replacing T, that is, the type before the argument, the second "addition" is the reference form after T in the function parameter list, and "and" is the actual form of the parameter after the function call. The following figure shows the correctness of the provisions in Mode 2:

Aids &-> A & A &-> A & A &-> A & A &-- > A & A &-> A & A &

Either way is fine. It's just that I feel that the second way goes around a little bit, and there is an inexplicable feeling that T first becomes int& (as shown in figure 1) and then becomes int. So, I recommend method one.

In the derivation of T, we adopt the following way: first, the type of formal parameter after function call is obtained from the superposition principle, and then this type is compared and matched with the type of formal parameter in the function parameter list, so as to get the type of T.

If a mismatch is found, the superposition rule is used again to "deduce" the type of T (which we will encounter in validation rule 3).

Take the situation in figure 1 as an example:

T & wresta (in the formal parameter list)

Int& Wassera (the actual type of formal parameter after the function call, determined by the superposition rule)

By comparison, T is int type.

two。 Validation Rule 2

The picture says:

Figure 2

This seems to validate rule 2, but take a look at the following figure:

Figure 3

I wonder if anyone would be surprised why void f (int& lfa) is called when an is clearly a right value reference. In other words, when did a become a left value?

Now, I'd like to tell you a conclusion (I believe many people know it, let's repeat it below):

According to the C++ standard, a named right value reference is treated as a left value. [note 6] the significance of this provision is that right-value references are originally used to implement mobile semantics, so you need to bind the memory address of an object and then have permission to modify the contents of that object, which is exactly the same as left-value binding. The difference between right-value binding and left-value binding is to determine the distinction when the function is overloaded. For the mobile construction member function and the mobile assignment operator member function, the combination of shape and real parameters is treated according to the right value reference; but inside the body of these two member functions, because the formal parameters are named, they are both regarded as left values. this parameter can be used to modify the internal state of the incoming object. In addition, the right value reference as a xvalue (final value) is originally used to empty its contents in mobile semantics at one time. Naming gives it a more durable lifetime, which is dangerous, so it is specified as a left-value reference unless the program explicitly specifies that its type is cast to a right-value reference.

Wikipedia address: http://zh.wikipedia.org/wiki/%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8

In addition, as can be seen from the image above, the difference between & & and & can be used as an overload flag.

Now, I believe everyone is no longer surprised. Looking back at figure 2, we understand that this validation is invalid and that ra is treated as a left value, which is equivalent to still validating rule 1. So, what should we do? Look at the following picture:

Figure 4

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

The reader can add the two f functions in figure 3 to the code in figure 4, and then write f (rt ()) in the main function; you will get an output like "right: 1". In order to shorten the length of the article, we will not take a screenshot here. Please verify it for yourself.

With regard to the code in figure 4, say the following:

1. As mentioned earlier, named right-value references are treated as left-value references, so, for experimental purposes, you can't pass named right-value references to the function wai (), so we pass unnamed right-value references such as function return values.

two。 If we return a reference to a local variable or a temporary object (for example, in the rt () function, write int await 1 return a temporary object, even if we put it globally, it won't work, because a copy of a copy of a before + + is returned as a temporary object), the result is incorrect (you can't get an output of 1). (the specific reason is not clear at the moment. It may be that the space of the temporary variable is overwritten (rewritten) when the later code is executed, and the exact answer is not found in the next disassembly step (not very well in the following assembly). Here please Daniel who knows the reason for your advice. Thank you very much.)

3. As you can see in figure 4, the rt () function must cast the global variable a to int&& and then return, otherwise, if it is written as return a, the compiler will generate an error similar to "unable to bind the right reference to the left value" because the named right reference an is regarded as the left value.

Const in 4.void wai (const T & Wiga) cannot be saved because non-constant references (T &) cannot accept right-value references.

Const in 5.void nei (const int& const int&) cannot be saved either, as you can see in figure 4, when nei is executed in wai (); when it is of type const int&.

Let's briefly talk about the derivation of T:

Const T & Whista (in the parameter list)

Const int& Wassera (the actual type of wencha after the function call)

By comparison, T is int type.

At this point, we can confirm that the red An in Table 1 is correct and the statement of A & is wrong.

3. Validation rule 3

The picture says:

Let's just talk about the derivation of T. As follows:

Type & Whista (type of wimpa in the parameter list)

Int& Wassera (the actual type of wencha after the function call)

Obviously, there is no direct match at this time. Here we use Table 2 (because Table 2 is more intuitive than Table 1), and deduce that T is of type int&.

4. Validation rule 4

The picture says:

First of all, here is one point. As we said earlier, non-constant left-value references cannot accept right-value references. In the figure above, void nei (int& _ indexa), watta is of type int&&, so how does the nei (watta); in rt () pass?

Don't forget that although wtreasa is displayed as an int&& type, it is a named right value reference, so it can be handled as a left value reference and can be passed naturally. If we change void nei (int& Natura) to void nei (int&& Natura) and fail to pass it (Wallera is regarded as int&, int&& cannot accept int&), readers can try it for themselves.

Let's talk about the derivation of T again:

Type & Whista (type of wimpa in the parameter list)

Int&& witera (the actual type of wencha after the function call, regardless of Clear11 regarding it as int&)

By contrast, T is known to be int type.

At this point, the four reference superposition rules and the corresponding template parameter type derivation are done, thank you!

Postscript:

I like to study deeply, like to explore, and seek truth from facts; but on the other hand, I really have little talent and limited ability, so I can only do some basic work. But even so, there will inevitably be omissions and even mistakes. Here, in

I sincerely ask you to criticize and correct them, and do not hesitate to give us advice. Your criticism is the source of continuous progress!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report