Heim  >  Artikel  >  Backend-Entwicklung  >  Der Unterschied und Zusammenhang zwischen auto und decltype in den neuen Funktionen von C++11

Der Unterschied und Zusammenhang zwischen auto und decltype in den neuen Funktionen von C++11

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

Der Unterschied und die Verbindung zwischen Auto und Decltype in den neuen Funktionen von C++11

1. Einführung in Auto

Beim Programmieren muss man oft auf den Wert achten eines Ausdrucks in eine Variable: Wenn Sie eine Variable deklarieren, müssen Sie genau wissen, um welchen Typ es sich handelt. Allerdings ist dies (besonders bei Vorlagen) nicht einfach und manchmal gar nicht möglich. Um dieses Problem zu lösen, führt der neue C++11-Standard den automatischen Typspezifizierer ein, der es dem Compiler ermöglicht, den Typ des Ausdrucks für uns zu analysieren. Es unterscheidet sich von den Originalen, die nur einem bestimmten Typspezifizierer (z. B. int) entsprechen. Mit auto kann der Compiler die Typableitung über Anfangswerte durchführen. Dadurch wird der Typ der definierten Variablen erhalten, sodass die von auto definierte Variable einen Anfangswert haben muss.

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

Der Typ des Elements hier wird vom Compiler berechnet, indem er während des Kompilierungsprozesses die Typen von val_1 und val_2 hinzufügt. Wenn es val_1(int) + val_2(double) ist, ist der Elementtyp der doppelte Datentyp, daher muss der anfängliche Basisdatentyp aller Variablen der Regenausrüstung gleich sein. Hier muss unbedingt zwischen Datentypen und Typmodifikatoren unterschieden werden! !

int i = 3;
auto a = i,&b = i,*c = &i;//正确: a初始化为i的副本,b初始化为i的引用,c为i的指针.
auto sz = 0, pi = 3.14;//错误,两个变量的类型不一样。
Der vom Compiler abgeleitete automatische Typ stimmt manchmal nicht genau mit dem Typ des Anfangswerts überein. Der Compiler ändert den Ergebnistyp entsprechend, um ihn konsistenter zu machen die Initialisierungsregeln.

Wie wir alle wissen, bedeutet die Verwendung einer Referenz tatsächlich die Verwendung des referenzierten Objekts. Insbesondere wenn die Referenz als Anfangswert verwendet wird, ist der Wert des referenzierten Objekts tatsächlich an der Initialisierung beteiligt Objekt. Zu diesem Zeitpunkt verwendet der Compiler den Typ des Referenzobjekts als Typ von Auto:

int i = 0 ,&r = i;//定义一个整数i,并且定义r为i的应用.
auto a = r; //这里的a为为一个整数,其值跟此时的i一样.
Es ist ersichtlich, dass Auto die Referenz im Allgemeinen ignoriert Ignorieren Sie die Konstante der obersten Ebene, aber die zugrunde liegende Konstante wird beibehalten, z. B. wenn der Anfangswert ein Zeiger auf eine Konstante ist:

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)
Wenn Sie daraus schließen möchten Der Typ „auto“ ist eine Konstante der obersten Ebene. Sie müssen explizit darauf hinweisen:

const auto f = ci;
Sie können den Referenztyp auch auf „auto“ festlegen. In diesem Fall gelten weiterhin die ursprünglichen Initialisierungsregeln apply (const, das für Referenzdeklarationen verwendet wird, sind alle zugrunde liegende const):

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

Manchmal werden wir auf diese Situation stoßen der Typ der Variablen, die aus dem Ausdruck definiert werden soll, aber Sie möchten die Variable nicht mit dem Wert des Ausdrucks initialisieren. Es ist auch möglich, dass der Rückgabetyp der Funktion der Werttyp eines Ausdrucks ist. In diesen Fällen ist auto machtlos, daher führt C++11 einen zweiten Typspezifizierer ein, decltype, der zum Auswählen und Zurückgeben des Datentyps des Operanden verwendet wird. Während dieses Vorgangs analysiert der Compiler nur den Ausdruck und ermittelt seinen Typ, berechnet jedoch nicht tatsächlich den Wert des Ausdrucks.

decltype(f()) sum = x;// sum的类型就是函数f的返回值类型。
Hier ruft der Compiler die f-Funktion nicht wirklich auf, sondern analysiert den Rückgabewert der f-Funktion als definierten Summentyp.

Grundsätzlich ist die Funktion von decltype der von auto sehr ähnlich, daher werde ich sie nicht einzeln auflisten. Eine weitere Verwendung für decltype ist der in C++11 eingeführte Postfix-Rückgabetyp.

3. Der Unterschied zwischen decltype und auto

Die Art und Weise, wie decltype mit Konstanten und Referenzen der obersten Ebene umgeht, unterscheidet sich geringfügig von auto. Wenn der von decltype verwendete Ausdruck eine Variable ist, gibt decltype den Typ zurück der Variablen (einschließlich Konstante und Referenzen der obersten Ebene).

Es gibt einige Dinge, die es zu beachten gilt, wenn es um decltype geht. Schauen wir uns zunächst den folgenden Code an:

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

Wenn der Inhalt des Ausdrucks eine Dereferenzierungsoperation ist, wird decltype dies tun Rufen Sie den Referenztyp ab. Wie wir wissen, kann die Dereferenzierung eines Zeigers das Objekt erhalten, auf das der Zeiger zeigt, und wir können diesem Objekt auch einen Wert zuweisen. Daher ist der Ergebnistyp von decltype(*p) int&.

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.

Ein weiterer wichtiger Unterschied zwischen decltype und auto besteht darin, dass der Ergebnistyp von decltype eng mit der Ausdrucksform zusammenhängt. Es gibt eine Situation, die besondere Aufmerksamkeit erfordert: Wenn für den von decltype verwendeten Ausdruck ein Klammerpaar zum Variablennamen hinzugefügt wird, kann der erhaltene Typ von dem ohne Klammern abweichen. Wenn decltype eine Variable ohne Klammern verwendet, ist das Ergebnis der Typ der Variablen. Wenn Sie dieser Variablen jedoch eine oder mehrere Klammerebenen hinzufügen, behandelt der Compiler diese Variable als Ausdruck. Die Variable ist ein spezieller Ausdruck, der als L-Wert verwendet werden kann, sodass ein solcher decltype den Referenztyp zurückgibt:

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中文网!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn