C++11: type derivation and trace function return type Decltype

Source: Internet
Author: User

    Reference article: Https://blogs.oracle.com/pcarlini/entry/c_11_tidbits_decltype_part
    Decltype is the first new C + + 11 feature implemented by GCC. It actually originated from a rather old GNU extension keyword--__typeof__. This non-standard keyword can also be used in the C language, and the GNU Compiler Collection Professional user may be more familiar with it. In 2008, the GCC 4.3.x realized this feature, while removing some of the drawbacks of __typeof__. Now, the Decltype and __decltype two keywords are available in GCC, which can only be used in C + + 11 mode, which may be applied to both C + + 11 and C + + 98 modes. The __typeof__ has been discontinued.
    Let's look at the basic use of decltype. In a nutshell, the Decltype keyword is used to query the type of an expression. However, this is only the basic usage. When this simple statement is combined with the other features of C + + 11, some unexpected interesting usages arise. The syntax of Decltype is
    Decltype (expression)
    The parentheses here are essential. According to the previous statement, Decltype's role is "type of query expression", so the effect of the above statements is to return the type of expression expressions. Note that Decltype is simply the type of the "query" expression and does not "evaluate" the expression. Let's look at one of the most basic examples:
    Const int&& foo (); int i;
    struct A {double x;}; CONST * A = new A ();
    Decltype (foo ()) x1;  Const int&& (1) decltype (i) X2;  Int (2) decltype (a->x) x3;  Double (3) Decltype ((a->x)) x4; double& (4)
    The traditional __typeof__ has a rather unpopular place where reference types are not handled well. And Decltype does not have this problem. and Decltype actually better fit into the C + + 11 type system, looking at a more complex example:
    int i; float F; Double D;
    typedef decltype (i + f) type1;  float typedef decltype (f + d) type2;  Double typedef decltype (F < D) Type3; bool
    As the above example shows clearly, Decltype is able to handle the problem of type conversion well.

    You may have questions about (4) in the code above. Why Decltype ((a->x)) would be double&? This is determined by the definition of decltype. The rule of Decltype discriminant is still quite complicated: for Decltype (e), its discriminant result is affected by the following conditions: 1.
    If E is an identifier or an access expression for a class member, then Decltype (e) is the type of entity that E represents. If there is no such type or E is an overloaded set of functions, then the program is wrong ((2) and (3) in the previous example), and 2. If E is a function call or an overloaded operator call (ignoring brackets outside e), then Decltype (e) is the return type of the function ((1) in the previous example);
    If E is not in the case described above, it is assumed that the type of E is T: When E is an lvalue, Decltype (e) is t&; otherwise (E is an rvalue), Decltype (e) is t (in the above example (4) that is the case. In this example, E is actually (a->x), because of this parenthesis, so it does not belong to the previous two cases, so should be based on this article as a criterion. and (A->x) is an lvalue, so it returns double &).
    What's the use of decltype to say so much? In fact, Decltype is very useful in complex template programming. However, this needs to be combined with the Auto keyword we mentioned earlier. For a classic example, take a look at the following code:
    ??? Foo (T T, u u) {
    return T + u; }
    Question mark what should I fill out here?
    The point is that we're working on templates, so we don't know the actual type of T and U. Even though these two template values are actually C + + built-in types, we don't know exactly what their type is. In the past, in the GNU C + + Runtime library, we could write pretty ugly code using the __typeof__ extension we said earlier:
    Decltype ((* (t*) 0) + (* (u*) 0)) foo (T T, u u) {
    return T + u; }
    In c++11, we can use the Auto keyword:
    Auto Foo (T T, u u), Decltype (t + u) {
    return T + u; }
    It looks a lot better! This is now supported by the language level.

    Finally, let's look at a more practical example. There is a piece of code in the GCC c++11 Runtime Library:
    Template<typename _iteratorl, TypeName _iteratorr>
    Inline Auto operator-(const reverse_iterator<_iteratorl>& __x, const reverse_iterator<_ iteratorr>& __y), Decltype (__y.base ()-__x.base ()) {
    Return __y.base ()-__x.base (); }
    Now, this code should be clearer. This actually solves a real bug in the C + + 98 implementation. In the case of the GCC version of C + + 98, this code is:
    Template<typename _iteratorl, TypeName _iteratorr>
    Inline typename Reverse_iterator<_iteratorl>::d ifference_type operator-(const Reverse_iterator<_iterat orl>& __x, const reverse_iterator<_iteratorr>& __y) {
    Return __y.base ()-__x.base (); }
    This code applies only if the difference_type of the two parties is the same.

C++11: type derivation and trace function return type Decltype

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.