自動およびdecltypeの使用
自動
C ++プログラミングでは、式の値を変数に割り当てる必要があることが多く、変数を宣言するときに変数のタイプを明確に知る必要があります。ただし、これは簡単なことではなく、まったく不可能な場合もあります。この問題を解決するために、新しいC ++ 11標準では、自動型指定子が導入されました。これにより、コンパイラーは式の型を分析できます。特定のタイプ指定子(intなど)にのみ対応する元のタイプとは異なります。autoを使用すると、コンパイラは初期値から型推定を実行できます。定義された変数のタイプを取得するには、autoによって定義された変数に初期値が必要です。次のように:
auto i; // error: declaration of variable 't' with deduced type 'auto' requires an initializer
//因此我们在使用auto时,必须对该变量进行初始化。
auto i= 0; //0为int类型,auto自动推导出int类型
auto j = 2.0; //auto 自动推导出类型为float
int a = 0;
auto b = a; //a 为int类型
auto &c = a; //c为a的引用
auto *d = &a; //d为a的指针
auto i = 1, b = "hello World"; //error: 'auto' deduced as 'int' in declaration of 'i' and deduced as 'const char *' in declaration of 'b'
/* auto 作为成员变量的使用*/
class test_A
{
public:
test_A() {
}
auto a = 0; //error: 'auto' not allowed in non-static class member
static auto b = 0; //error: non-const static data member must be initialized out of line
static const auto c = 0;
};
/*c11 中的使用*/
auto func = [&] {
cout << "xxx";
};
// 不关心lambda表达式究竟是什么类型
auto asyncfunc = std::async(std::launch::async, func);
// 懒得写std::futurexxx等代码
自動使用の制限
- autoの使用はすぐに初期化する必要があります。そうしないと、タイプを導出できません。
- 自動で1行に複数の変数を定義する場合、各変数の導出を曖昧にすることはできません。そうしないと、コンパイルが失敗します。
- autoを関数パラメーターとして使用することはできません
- Autoは、クラスの非静的メンバー変数として使用できません
- Autoは配列を定義できませんが、ポインタを定義できます
- autoはテンプレートパラメータを推測できません
自動の派生ルール
- 参照またはポインターとして宣言されていない場合、autoは、等しい符号とconstおよびvolatile修飾の右側にある参照タイプを無視します。
- 参照またはポインターとして宣言された場合、autoは、等号の右側にある参照と、constおよびvolatile属性を保持します。
const int a = 0;
auto b = a;
auto &c = a;
c = 3;
//error: cannot assign to variable 'c' with const-qualified type 'const int &'
//note: variable 'c' declared const here
decltype
decltypeは式のタイプを推測するために使用されます。ここでは、コンパイラが式のタイプを分析するためにのみ使用されます。式は実際には計算されません。
int fun(){
return 0; }
decltype(fun()) a;
decltype(fun()) b = 5;
int fun2(int a){
return 0; }
int c = 0;
decltype(fun2(c)) a;
decltype(fun2(c)) b = 5;
注:decltypeは参照とconstを無視しません、autoのような揮発性属性、decltypeは式参照とconstとvolatile属性を保持します
decltypeの推論規則
decltype(exp)の場合:
- expは式、decltype(exp)はexpと同じです
- expは関数呼び出しであり、decltype(exp)は関数の戻り値タイプと同じです。
- その他の場合、expが左辺値の場合、decltype(exp)はexpタイプの左辺値参照です。
int a = 0, b = 0;
decltype(a + b) c = 0; // c是int,因为(a+b)返回一个右值
decltype(a += b) d = c;// d是int&,因为(a+=b)返回一个左值
d = 20;
cout << "c " << c << endl; // 输出c 20
autoとdecltypeの組み合わせ
autoとdecltypeは通常、関数の戻り値のタイプを導出するために一緒に使用されます。例は次のとおりです。
template<typename , typename U>
return_value add(T t, U u) {
// t和v类型不确定,无法推导出return_value类型
return t + u;
}
上記のコードは、tとuのタイプが不確実であるためです。したがって、戻り値のタイプを推測する方法については、次のように考えることができます。
template<typename T, typename U>
decltype(t + u) add(T t, U u) {
// t和u尚未定义
return t + u;
}
このコードはC ++ 11でコンパイルできません。これは、decltype(t + u)が推定され、tとuが定義されていない場合、コンパイルエラーが発生するため、return typepostfixと呼ばれる次のメソッドがあります。 :
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
戻り値のポストタイプ構文は、関数の戻り値タイプがパラメーターに依存するという問題を解決することですが、戻り値タイプを判別することは困難です。