C ++ 0x feature in VC10 Part 3: Declaration type

Source: Internet
Author: User

 

Translated by VC10C ++ 0x feature part 3: Declaration type 

Luo chaohui (http://www.cnblogs.com/kesalin/) This article follows the "signature-non-commercial use-keep consistent" Create public agreement

 

Introduction 

This seriesArticleThis section describes the C ++ 0x features supported by Microsoft Visual Studio 2010. Currently, there are three parts.
Part 1: Introduce Lambdas, auto with new meaning, and static_assert;
Part 2 (1, 2): Describes the right value reference (rvalue references );
Part 3: decltype)

C ++ 0x feature in VC10 part 1, 2, and 3 (in DOC and PDF formats): Click here to download

This document is part 3.

 

Today I want to talk about decltype, which enables the perfect forwarding function to return anything of any type. This is an interesting feature for people who write highly generic data.

 

ReturnClassTypeProblem

C ++ 98/03 has an interesting blind spot: given an image X * y , X And Y Is of any type, but you cannot know X * y . Assume that X Yes Watts Type, Y Yes Seconds Type, that X * y May be of the joules type. Given Declaration Print (const T & T) , Call Print (x * Y) , Here T Will be pushed Joules Type. However, this is not the case: When you write a function Multiply (const A & A, const B & B) You cannot specify its generic return type. Even if the instance is converted Multiply <A, B> () The compiler also knows X * y Type, but you just cannot get such information (that is, the return type ). Keywords in C ++ 0x Decltype Eliminate this blind spot and let you say" Multiply () Return X * y ". ( Decltype Is the abbreviation of "declared type". I will read it as the homophone "speckle type ".)

 

Decltype: Mode

The following is a fully generalized function factor for encapsulating the + () operator. This "addition" factor is not a template, but it has a template function. This template function includes two parameters of any type (of course different types) and adds them, then return the result of any type (which may be different from the two parameter types.

 

C:/temp> type plus. cpp

# Include <algorithm>

# Include <iostream>

# Include <iterator>

# Include <ostream>

# Include <string>

# Include <utility>

# Include <vector>

Using namespace STD;

 

Struct plus {

Template <typename T, typename u>

Auto operator () (T & T, U & U) const

-> Decltype (Forward <t> (t) + forward <u> (u )){

Return forward <t> (t) + forward <u> (U );

}

};

 

Int main (){

Vector <int> I;

I. push_back (1 );

I. push_back (2 );

I. push_back (3 );

 

Vector <int> J;

J. push_back (40 );

J. push_back (50 );

J. push_back (60 );

 

Vector <int> K;

 

Vector <string> S;

S. push_back ("cut ");

S. push_back ("flu ");

S. push_back ("Kit ");

 

Vector <string> T;

T. push_back ("e ");

T. push_back ("ffy ");

T. push_back ("Tens ");

 

Vector <string> U;

 

Transform (I. Begin (), I. End (), J. Begin (), back_inserter (K), plus ());

Transform (S. Begin (), S. End (), T. Begin (), back_inserter (u), plus ());

 

For_each (K. Begin (), K. End (), [] (int n) {cout <n <"";});

Cout <Endl;

 

For_each (U. Begin (), u. End (), [] (const string & R) {cout <r <"";});

Cout <Endl;

}

 

C:/temp> Cl/ehs/ nologo/W4 plus. cpp

Plus. cpp

 

C:/temp> plus

41 52 63

Cute fluffy kittens

 

Take C ++ 98/03 <Functional> In STD: plus <t> (No change in C ++ 0x). The latter is a class template and you have to pass the template parameter type for calling. Plus <int> () And Plus <string> () , Re-declare the element type once. And the form of the latter is T operator () (const T & X, const T & Y) Non-template function call operator. If implicit type conversion is not used, the east and west of the two different types cannot be added, let alone three different types. (Note: two parameter types + one return type ). (You can pass String And Const char * Type of real parameters for calling Const plus <string> () Then, before the concatenation operation, based on the second parameter ( Const char * ) Construct a temporary String ). In addition, because its parameter is Const T & In the formatMove Meaning to get a good place. Plus The above problems are avoided: Call Plus () You do not need to repeat the type of the element. It can also handle the situation of "3" different types, and it uses perfect forwarding, so it can use the move semantics.

 

Trailing return type

 

Now let's take a look at this template function call operator:

 

Template <typename T, typename u>

AutoOperator () (T & T, U & U) const

-> Decltype (Forward <t> (t) + forward <u> (u )){

Return forward <t> (t) + forward <u> (U );

}

In this Auto AndFor (Auto I = V. Begin (); I! = V. End (); ++ I) The meanings in are completely different. In For, it refers to "initializing the object type as the object type", and here it refers to "this function has Trailing-return-type Only after the real parameter is specified can we determine what type it returns. "(in proposal n2857 of C ++ 0x, this is called" Late-specified return type  ", But it will be renamed as" Trailing-retrun-type "(Proposal n2859 )). This seems to be very similar to how Lambda functions specify the return type. Actually, they are similar. Lambda The return type of the function must appear in Lambda Guide [] After (right side ). Here,Decltype-powered The type must also be output in the function parameter T And U After (right side ). Autot And U It can be seen, but function parameters T And U Not to mention, why? Decltype . (Technically speaking, Decltype (Forward <t> (* static_cast <t *> (0) + forward <u> (* static_cast <u *> (0 )) ) Can appear on the left side, but it looks uncomfortable ).

 

As for the returned sentence, use and passDecltypeIn the same form, is to ensure that in any situation can work correctly. (Burst quiz: Why is decltype (t + u) not right ?). In this case, repeat is inevitable, but there is no risk because it is concentrated-only once and the code generation position is near.

 

Another example

Taking into account the integrity of the example, the following is an example of "3" different types:

 

C:/temp> type mult. cpp

# Include <algorithm>

# Include <iostream>

# Include <iterator>

# Include <ostream>

# Include <utility>

# Include <vector>

Using namespace STD;

 

Struct multiplies {

Template <typename T, typename u>

Auto operator () (T & T, U & U) const

-> Decltype (Forward <t> (t) * Forward <u> (u )){

Return forward <t> (t) * Forward <u> (U );

}

};

 

Class Watts {

Public:

Explicit Watts (const int N): M_n (n ){}

Int get () const {return M_n ;}

PRIVATE:

Int M_n;

};

 

Class seconds {

Public:

Explicit seconds (const int N): M_n (n ){}

Int get () const {return M_n ;}

PRIVATE:

Int M_n;

};

 

Class joules {

Public:

Explicit Joules (const int N): M_n (n ){}

Int get () const {return M_n ;}

PRIVATE:

Int M_n;

};

 

Joules operator * (const Watts & W, const seconds & S ){

Return Joules (W. Get () * S. Get ());

}

 

Int main (){

Vector <Watts> W;

W. push_back (Watts (2 ));

W. push_back (Watts (3 ));

W. push_back (Watts (4 ));

 

Vector <seconds> S;

S. push_back (seconds (5 ));

S. push_back (seconds (6 ));

S. push_back (seconds (7 ));

 

Vector <joules> J;

 

Transform (W. Begin (), W. End (), S. Begin (), back_inserter (J), multiplies ());

 

For_each (J. Begin (), J. End (), [] (const joules & R) {cout <R. Get () <Endl ;});

}

 

C:/temp> Cl/ehs/ nologo/W4 mult. cpp

Mult. cpp

 

C:/temp> Mult

10

18

28

 

You may ask "are all these points really necessary?". The answer is yes, and it is necessary. I have introduced how perfect forwarding and decltype make it easier to use computational Function Factors (no need to re-declare element types ), it is more flexible (different parameters and return types can be mixed) and more efficient (with move semantics ). The most important thing is that perfect forwarding and decltype allow you to write more concise and clear code generation, the inflexible and inefficient code generation is not concise and clear-which we cannot ignore.

 

HighLevel Rules

DecltypeThere are some rules to drive. However, it doesn't matter if you follow the above pattern and can work normally. I seldom say C ++ that way, but here it is.

Although mostDecltypeThe above mentioned model should be followed,DecltypeIt can also be used in other environments. In those cases, you usedDecltypeIn the advanced mode of C ++ 0x proposal n2857 7.1.6. 2 [DCL. type. Simple]/4.

 

Wait,AlsoThere are some requirementsDescriptionOf

DecltypeIs the fifth and the last C ++ 0x core language feature added to VC10. VC10 CTP does not exist, but VC10 Bata 1 does. In addition, there are many c ++ 0x standard library features in VC10 Beta 1. I will introduce them in subsequent articles.

Stephen T. lavavej

Visual c ++ libraries developer

Published Wednesday, April 22,200 9 am by vcblog

Translation: Floating white clouds

 

(When reprinting, please indicate the author and the place of departure. If not approved, do not use it for commercial purposes)

<Full text>

 


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.