「C ++ 11コードの最適化とエンジニアリングレベルのアプリケーションの詳細なアプリケーション」第1章学習記録

「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&

 

おすすめ

転載: www.cnblogs.com/snake-fly/p/12657612.html