C++11 auto と decltype

自動

プログラミングでは、式の値を変数に代入する必要があることがよくあります。そのためには、変数を宣言するときに式の型を明確に知っておく必要があります。ただし、これを行うのはそれほど簡単ではなく、場合によってはまったく実行できないこともあります。この問題を解決するために、新しい C++11 標準では auto 型指定子が導入されており、これによりコンパイラが式の型を分析できるようになります。

特定の型 (double など) にのみ対応する元の指定子とは異なり、auto を使用すると、コンパイラーは初期値から変数の型を推測できます明らかに、auto で定義された変数には初期値が必要です

//由val1和val2相加的结果可以推断出item的类型
auto item = val1 + val2; // item初始化为val1和val2相加的结果

auto を使用すると、1 つのステートメントで複数の変数を宣言することもできます宣言ステートメントには 1 つの基本データ型しか含めることができないため、ステートメント内のすべての変数の初期基本データ型は同じである必要があります

auto i = 0, *p = &i;       // 正确:i是整数,p是整型指针
auto sz = 0, pi = 3.14;    // 错误:sz和pi的类型不一样

コンパイラーによって推論された auto 型が初期値の型とまったく同じではない場合があり、コンパイラーは結果の型を適切に変更して、初期化規則との一貫性を高めます

まず、ご存知のとおり、参照を使用するということは、実際には参照先のオブジェクトを使用することになります。特に参照が初期値として使用される場合、実際に初期化に関与するのは参照先のオブジェクトの値です。このとき、コンパイラは参照されるオブジェクトの型を auto の型として使用します。

int i = 0, &r = i;
auto a = r;

次に、auto は通常、最上位の const を無視しますが、たとえば、初期値が定数へのポインタである場合、基礎となる const は通常予約されます。

const int ci = i, &cr = ci;
auto b = ci;    // b是一个整数(ci的顶层const特性被忽略掉了)
auto c = ci;    // c是一个整数(cr时ci的别名,ci本身是一个顶层const)
auto d = &i;    // d是一个整型指针
auto e = &ci;   // e是一个指向整数常量的指针(对常量对象取地址是一种底层const)

推論された auto 型をトップレベルの const にしたい場合は、それを明示的に指定する必要があります。

const auto f = ci;  // ci的推演类型是int,f是const int

参照のタイプを auto に設定することもできます。その場合でも、元のルールが引き続き適用されます。

auto &g = ci;          // g是一个整型常量的引用,绑定到ci
auto &h = 42;          // 错误:不能为非常量引用绑定字面值
const auto &j = 42;    // 正确:可以为常量引用绑定字面值

auto 型の参照を設定する場合、初期値の最上位の定数プロパティは引き続き保持されます。いつものように、参照を初期値にバインドする場合、その定数はトップレベルの定数ではありません。

1 つのステートメントで複数の変数を定義するには、記号 & と * は特定の宣言子にのみ従属し、基本データ型の一部ではないため、初期値は同じ型でなければならないことに注意してください。

auto k = ci, &l = i;
auto &m = ci, *p = &ci;
// 错误:i的类型是int而&ci的类型是const int
auto &n = i, *p2 = &ci;

デクタイプ

定義する必要がある変数の型を式の型から推測したいが、その式の値で変数を初期化したくないという状況に遭遇することがありますこの需要を満たすために、C++11 では型指定子 decltype を導入しています。これは、オペランドのデータ型を選択して返すために使用されます。

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

コンパイラは、トップレベルの const と参照を auto とは少し異なる方法で処理します。decltype で使用される式が変数の場合、decltype は変数の型 (トップレベルの const と参照を含む) を返します。

const int ci = 0, &cj = ci;
decltype(ci) x = 0;          // x的类型是const int
decltype(cj) y = x; 		 // y的类型是const int&,y绑定到变量x
decltype(cj) z;				 // 错误:z是一个引用,必须初始化

decltype で使用される式が変数でない場合、decltype は式の結果に対応する型を返します。一部の式は参照型を decltype に返します。

一般に、これが発生した場合、式の結果オブジェクトが代入ステートメントの左辺値として使用できることを意味します。

// decltype的结果可以是引用类型
int i = 42, *p = &i, &r = i;
decltype(r + 0) b;  // 正确:加法的结果是int,因此b是一个未经初始化的int
decltype(*p) c;     // 错误:c是int&,必须初始化

r は参照であるため、decltype(r) の結果は参照型になります。

結果の型を r が指す型にしたい場合は、r+0 など、式の一部として r を使用できます。明らかに、この式の結果は参照ではなく具体的​​な値になります。

一方、式の内容が逆参照操作の場合、 decltype は参照型を取得しますしたがって、decltype(*p) の結果の型は int ではなく int& になります。

decltype が括弧なしで変数を使用する場合、結果は変数の型になります。1 つ以上の括弧の層が変数に追加される場合、コンパイラーはそれを式として扱うため、そのような decltype は参照型を取得します。

// decltype的表达式如果是加上了括号的变量,结果将是引用
decltype((i)) d;    // 错误:d是int&,必须初始化
decltype(i) e;      // 正确:e是一个int

auto と decltype の違い

  1. auto 型指定子は、コンパイラを使用して変数の初期値を計算し、その型を推測するため、auto 変数を初期化する必要がありますdecltype を使用すると、コンパイラは式を分析してその型を取得できますが、実際には式の値を計算しないため、decltype 変数を必ずしも初期化する必要はありません
  2. コンパイラによって推論された auto 型が初期値の型とまったく同じではない場合があり、コンパイラは初期化ルールとの一貫性を高めるために結果の型を適切に変更します。たとえば、auto は通常、最上位の const を無視し、最下位の const を保持します。対照的に、 decltype は変数の最上位の const を保持します
  3. auto とは異なり、decltype の結果の型は式の形式と密接に関係しており、変数名に括弧を付けた場合と括弧なしの場合では得られる型が異なります。decltype が括弧なしで変数を使用する場合、結果は変数の型になります。変数に 1 つ以上の括弧が追加されている場合、コンパイラは参照型を推測します

おすすめ

転載: blog.csdn.net/TABE_/article/details/126574003