「C ++ 11コードの最適化とエンジニアリングレベルのアプリケーションの詳細なアプリケーション」第1章学習記録
1.1タイプの推論
1.1.1自動型控除
Autoは実際の型宣言を表すのではなく、型宣言の「プレースホルダー」を表します。
autoを使用して宣言された変数は、コンパイラーが実際の型を推測し、コンパイル時にautoプレースホルダーを実際の型に置き換えられるように、すぐに初期化する必要があります。
autoの派生規則:(cv qualifier:constとvolatileをまとめて)
(1)ポインタまたは参照として宣言されていない場合、autoの導出結果と初期化式は、参照とcv修飾子の型を破棄します。
例えば。int x = 0;
const self e = x; // e-> const int
自動f = e; // f-> int
(2)ポインターまたは参照として宣言された場合、autoの派生結果は式のcv属性を維持します。
たとえば、int x = 0;
const auto&g = x; // g-> const int&
自動h = g; // h-> const int&
自動の制限:
(1)関数パラメータにAutoは使用できません。
(2)自動は非静的メンバー変数には使用できません。
(3)Autoは配列を定義できません。
(4)Autoはテンプレートパラメータを取得できません。
例えば。
[root @ 192 C ++ 11]#cat funcautodemo.cpp
#include <iostream>
using namespace std;
struct Foo
{
auto var1_ = 0; // autoは非静的メンバー変数に使用できません
static const auto var2_ = 0;
};
int func(auto x)// 関数のパラメーターにautoは使用できません
{
int i = x;
return 0;
}
テンプレート<typename T>構造体バー{};
int main()
{
int arr [10] = {0};
auto aa = arr;
auto rr [10] = arr; // autoは配列を定義できません
Bar <int> bar;
Bar <auto> bb = bar; // autoはテンプレートパラメータを
返すことができません return 0;
}
[root @ 192 C ++ 11]#g ++ funcautodemo.cpp -o funcautodemo -std = c ++ 11
funcautodemo.cpp:5:5:エラー:非静的データメンバーが宣言されましたプレースホルダー付き 'auto'
5 | auto var1_ = 0;
| ^ ~~~
funcautodemo.cpp:9:10:エラー:'auto'のパラメーター宣言での使用は、 '-std = c ++ 14'または '- std = gnu ++ 14 '
9 | int func(auto x)
| ^ ~~~
funcautodemo.cpp:In function' int main() ':
funcautodemo.cpp:21:10:error:' rr 'の配列として宣言「自動」
21 | auto rr [10] = arr;
| ^
〜funcautodemo.cpp:24:9:エラー:'auto'
24の無効な使用 | Bar <auto> bb = bar;
| ^ ~~~
funcautodemo.cpp:24:13:エラー:テンプレート引数1は無効です
24 | Bar <auto> bb = bar;
| ^
funcautodemo.cpp:24:20:エラー:初期化
24で'Bar <int>'を 'int'に変換できません| Bar <auto> bb = bar;
| ^ ~~
| |
| バー<int>
1.1.2 decltypeキーワード
式のタイプを取得する
上記のautoは、コンパイラが型を推定する前に変数を初期化する必要があります。初期化したくない場合は、宣言するだけで型を取得でき、その後decltypeを使用する必要があります。
例えば。
int x = 0;
decltype(x)y = 1; // y-> int
decltype(x + y)z = 0; // z-> int
const int&i = x;
decltype(i)j = y; // j-> const int&
const decltype(z)* p =&z; // p-> const int *
decltype(z)* pi =&z; // pi-> int *
decltype(pi)* pp =&pi; // pp-> const int **
Decltype(exp)派生規則:
(1)expは識別子、クラスアクセス式、decltype(exp)とexpは同じ型です
例えば。
クラスFoo
{
公衆:
static const int Number = 0;
int x = 0;
};
int n = 0;
揮発性const int&x = n;
decltype(n)a = n; // a-> int
decltype(x)b = n; // b-> volatile const int&
decltype(Foo :: Number)c = 0; // c-> const int
Foo foo;
decltype(foo.x)d = 0; // d-> int
(2)expは関数呼び出しであり、decltype(exp)の型と戻り値は同じです
例えば。
int&func_int_r(void); //左辺値
int && func_int_rr(void); //正しい値
int func_int(void); //純粋な右辺値
const int&func_cint_r(void); // Lvalue
const int && func_cint_rr(void); //右辺値
const int func_cint(void); //純粋な右辺値
const Foo func_cfoo(void); //純粋な右辺値
int x = 0;
decltype(func_int_r())a1 = x; // a1-> int&
decltype(func_int_rr())b1 = 0; // b1-> int &&
decltype(func_int())c1 = 0; c1-> int
decltype(func_cint_r())a2 = x; // a2-> const int&
decltype(func_cint_rr())b2 = 0; // b2-> const int &&
decltype(func_cint())c2 = 0; // c2-> int
decltype(func_cfoo())ff = Foo(); // ff-> const Foo
注:C 2はint、constは無視され、ffはconst Foo、constは無視されません。C++ 11仕様の説明によると、関数によって返されるintは純粋な右辺値であり、クラスタイプのみがcvを運ぶことができるためです修飾子、その他は一般にcv修飾子を無視します。
(3)それ以外の場合、expが左辺値の場合、decltype(exp)はexp型の左辺値参照です。それ以外の場合は、exp型と一致します。。
例えば。
struct Foo {int x;};
const Foo foo = Foo();
decltype(foo.x)a = 0; // a-> int
decltype((foo.x))b = a; // b-> const int&
int n = 0、m = 0;
decltype(n + m)c = 0; // c-> int
decltype(n + = m)d = c; // d-> int&