Home  >  Article  >  Backend Development  >  The difference and connection between auto and decltype in the new features of C++11

The difference and connection between auto and decltype in the new features of C++11

高洛峰
高洛峰Original
2017-01-23 14:34:321709browse

The difference and connection between auto and decltype in the new features of C++11

1. Introduction to auto

When programming, it is often necessary to pay the value of an expression to a variable. This needs to be done in When you declare a variable, you know exactly what type it is. However, doing this is not that easy (especially in templates), and sometimes it is not possible at all. In order to solve this problem, the new C++11 standard introduces the auto type specifier, which allows the compiler to analyze the type of the expression for us. It is different from the original ones that only correspond to a specific type specifier (such as int). auto lets the compiler perform type deduction through initial values. Thus, the type of the defined variable is obtained, so the variable defined by auto must have an initial value.

//由val_1 和val_2相加的结果可以推断出item的类型
auto item = val_1 + val_2;//item 类型初始化为val_1 + val_2相加后的类型,值为val_1+val_2相加的值。

The type of item here is calculated by the compiler by adding the types of val_1 and val_2 during the compilation process. If it is val_1(int) + val_2(double), then the type of item is double. Data type, so the initial basic data type of all variables of the rain gear must be the same. Be sure to distinguish between data types and type modifiers here! !

int i = 3;
auto a = i,&b = i,*c = &i;//正确: a初始化为i的副本,b初始化为i的引用,c为i的指针.
auto sz = 0, pi = 3.14;//错误,两个变量的类型不一样。

The auto type inferred by the compiler is sometimes not exactly the same as the type of the initial value. The compiler will appropriately change the result type to make it more consistent with the initialization rules.

This First, as we know, the use of references is actually a reference object. In particular, when the reference is used as the initial value, the real participation is actually the value of the reference object. At this time, the compiler uses the type of the reference object as the type of auto:

int i = 0 ,&r = i;//定义一个整数i,并且定义r为i的应用.
auto a = r; //这里的a为为一个整数,其值跟此时的i一样.

It can be seen that auto will ignore the reference. Secondly, auto will generally ignore the top-level const, but the bottom-level const will be retained, such as when the initial value is a pointer to a constant:

int i = 0;
const int ci = i, &cr = ci; //ci 为整数常量,cr 为整数常量引用 
auto a = ci;   // a 为一个整数, 顶层const被忽略
auto b = cr;   // b 为一个整数,顶层const被忽略
auto c = &ci;  // c 为一个整数指针.
auto d = &cr;  // d 为一个指向整数常量的指针(对常量对象区地址是那么const会变成底层const)

If you want to infer that the auto type is a top-level const, you need to explicitly point it out:

const auto f = ci;

You can also set the reference type to auto, in which case the original initialization rules still apply (const used for reference declarations are all underlying const):

auto &g = ci; //g是一个整数常量引用,绑定到ci。
auto &h = 42; // 错误:非常量引用的初始值必须为左值。
const auto &j = 42; //正确:常量引用可以绑定到字面值。

2. Introduction to decltype

Sometimes we will encounter this situation. We want to infer the type of variable to be defined from the expression, but we do not want to use the value of the expression to initialize it. variable. It is also possible that the return type of the function is the value type of an expression. At these times, auto is powerless, so C++11 introduces a second type specifier, decltype, which is used to select and return the data type of the operand. During this process, the compiler only analyzes the expression and obtains its type, but does not actually calculate the value of the expression.

decltype(f()) sum = x;// sum的类型就是函数f的返回值类型。

Here the compiler does not actually call the f function, but analyzes the return value of the f function as the defined type of sum.

Basically, the function of decltype is very similar to that of auto, so I won’t list them one by one. Another use for decltype is the postfix return type introduced in c++11.

3. The difference between decltype and auto

The way decltype handles top-level const and references is slightly different from auto. If the expression used by decltype is a variable, decltype returns the type of the variable. (Including top-level const and references).

const int ci = 42, &cj = ci;
  
decltype(ci) x = 0;  // x 类型为const int
auto z = ci;     // z 类型为int
  
decltype(cj) y = x;  // y 类型为const int&
auto h = cj;     // h 类型为int

There are some things worth noting about decltype. Let’s take a look at the following code first:

int i = 42, *p = &i, &r = i;
  
decltype(i) x1 = 0;    //因为 i 为 int ,所以 x1 为int
auto x2 = i;       //因为 i 为 int ,所以 x2 为int
  
decltype(r) y1 = i;    //因为 r 为 int& ,所以 y1 为int&
auto y2 = r;       //因为 r 为 int& ,但auto会忽略引用,所以 y2 为int
  
decltype(r + 0) z1 = 0;  //因为 r + 0 为 int ,所以 z1 为int,
auto z2 = r + 0;     //因为 r + 0 为 int ,所以 z2 为int,
  
decltype(*p) h1 = i;   //这里 h1 是int&, 原因后面讲
auto h2 = *p;       // h2 为 int.

If the content of the expression is a dereference operation, decltype will get the reference type. As we are familiar with, dereferencing a pointer can get the object pointed to by the pointer, and we can also assign a value to this object. Therefore, the result type of decltype(*p) is int&.

Another important difference between decltype and auto is that the result type of decltype is closely related to the expression form. There is one situation that requires special attention: for the expression used by decltype, if a pair of parentheses is added to the variable name, the type obtained may be different from that without parentheses. If decltype uses a variable without parentheses, the result is the type of the variable. But if you add one or more layers of parentheses to this variable, the compiler will treat this variable as an expression. The variable is a special expression that can be used as an lvalue, so such a decltype will return the reference type:

int i = 42;
  
//decltype(i)  int 类型
//decltype((i)) int& 类型

这里再指出一个需要注意的地方就是 = 赋值运算符返回的是左值的引用。换句话意思就是说 decltype(i = b)  返回类型为 i 类型的引用。仔细看下面这段代码:

int main()
{
  int i = 42;
  
  decltype(i = 41) x = i;
  
  auto y = i;
  
  auto& z = i;
  
  printf("i x y z 此时为: %d %d %d %d\n", i,x,y,z);
  
  i--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  x--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  y--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  z--;
  
  printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z);
  
  return 0;
}


运行结果为:

i x y z 此时为: 42 42 42 42
i x y z 此时为: 41 41 42 41
i x y z 此时为: 40 40 42 40
i x y z 此时为: 40 40 41 40
i x y z 此时为: 39 39 41 39

   

     由上面的代码和运行结果可以看出来,1.decltype(i = 41)中的赋值语句并没有真正的运行。2. decltype(i = 41)返回的其实是int&,也就是说x 其实是 i 的引用。

了解了auto 和 decltype后,以后在使用的过程中一定要分清两者的区别,防止在定义的时候产生const 与非const 以及引用 与非引用 的差别!!

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

更多C++11新特性中auto 和 decltype 区别和联系相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn