C++11 property summary of decltype class initialization list initialization return value

  • 2020-09-16 07:41:08
  • OfStack

Effect: Returns the type of an expression or variable

Return value rules:

If e is an lend (lvalue, or "addressable value"), decltype(e) returns T & If e is 1 end-of-life value (xvalue), the return value is T & & If e is a pure right value (prvalue), the return value is T

decltype() does not execute the expression in parentheses. decltype returns a type that is declared and cannot be used for pure judgment. For example, decltype (a) ==int is not allowed. It can only be used where the new variable is defined and the value is returned:


int a=1;
decltype ( a )  b  (equivalent to the int b ) 

If you add an extra parenthesis to a variable, it becomes an expression.


int a = 1;
int b=2;
decltype((a)) d=b // decltype((a)) 
 The return type int& . The reference has to be assigned an initial value, so the d Initial value must be assigned. 

If an expression is related to a pointer:

Set p to be a pointer to the int variable

decltype (*p) - returns int & The reference decltype (p) - returns int*, the pointer decltype ( & p) - returns int**, a pointer to a pointer.

Here's why 1 returns a reference instead of int: because *p returns essentially a reference, when we assign a value to *p, we change the value of the variable instead of making a copy, which is obviously the nature of a reference.

Using decltype in generic programming:

Combined with the tail-return type, this enables the return value to be inferred by the compiler without the programmer having to indicate it. Mainly used to write forward functions


int& foo(int& i);
float foo(float& f);

template <class T> 
auto transparent_forwarder(T& t) −> decltype(foo(t)) 
{
 return foo(t);
}

Without decltype, as in this example, we cannot determine which of the two alternative functions foo (t) is, because this is determined at run time. In this case, we cannot directly write the return value of the transparent_forwarder function.

There are many other examples. decltype is often used where variable types are difficult to determine, and templates are created to accommodate multiple types, so decltype is often used in generic programming to allow flexibility in defining variable types.

Class initialization

C++11 cannot be initialized before the data member declaration of a class unless it is a static variable of const:


class A
{
 static int i = 1; //correct, I have to assign a value here because const Constants must be assigned at declaration time 
 int num=2; //error Data members are not allowed to be initialized when declared within a class 
};

The problem with this is that although we only want to set an initial value for all the data members of an instance of this class, we have to define a constructor ourselves to do so.

Thus on c++11: allows the value to be initialized directly within the class (provided that the value is a constant expression).

Order: Intra-class initialization precedes constructor initialization, which overrides intra-class initialization. That is, if we define both the class initializers and our own constructors, the end result will be to assign data members to constructors as we wish.

Usage:


class A
{
 int num=2; //correct . C++11 Allows data members to be initialized when declared within a class 
 int a{7} // You can use curly braces to assign values, a=7 
};

Note: In C++11, there is still no change to the fact that static data members must be declared within the class and initialized outside the class.


class A
{
 static int d = 1; //error
};
int A::d = 1 //correct . 1 In general: initialization statements are placed in cpp File, class definitions are placed h file 

List initializes the return value

Before C++11, if we wanted to return a set of data, we had to construct a corresponding container in the subfunction and return it with the help of the container.


vector<int> process()
{
 vector<int> v={1,2,3,4}
 return v;
}

Under the new standard, we can return the literal value directly, which will be used in the construction of the container instead of having to construct it ourselves.


vector<int> process()
{
 return {1,2,3,4};
}

conclusion


Related articles: