C++のautoキーワードを用いた型推論の詳細解析

型推論の基本規則

C++11以降、autoキーワードは型プレースホルダとして再定義され、変数宣言時に明示的な型指定を不要にします。初期化式からコンパイラが型を自動推論します。基本形式は以下の通りです:

auto identifier = expression;

autoには修飾子を追加可能です:

const auto var = expr;
const auto& ref = expr;
volatile auto* ptr = expr;

規則1: 値による初期化(非参照・非ポインタ)

auto単体の場合、式の値がコピーされ、CV修飾子(const/volatile)は無視されます:

const int value = 10;
auto copy = value;  // copyはint型(const修飾が除去)

複数変数宣言時は型が一致する必要があります:

auto a = 5, b = 8;    // 成功: int型
auto x = 5, y = 3.14; // エラー: 型不一致

規則2: 参照/ポインタ型の宣言

auto& または auto* 形式では、CV修飾子が保持されます:

int base = 100;
const int const_base = base;
auto& ref1 = base;       // ref1: int&
const auto& ref2 = const_base; // ref2: const int&
auto* ptr = &const_base; // ptr: const int*

ポインタ型は明示的指定なしでも推論可能です:

double num = 2.718;
auto address = # // address: double*

規則3: ユニバーサル参照(auto&&)

右辺値に応じて参照種別が決定されます:

int lvalue = 50;
auto&& universal1 = lvalue;  // int& (左値参照)
auto&& universal2 = 200;    // int&& (右値参照)

初期化式の種類別推論挙動

参照型の式

参照型の式では参照性が無視され、参照先の型で推論されます:

int origin = 30;
int& ref_origin = origin;
const int& const_ref = origin;
auto val1 = ref_origin;   // val1: int
auto val2 = const_ref;    // val2: int
auto& val3 = const_ref;  // val3: const int&

初期化リスト

波括弧初期化の形式で挙動が異なります:

auto list = {1, 2, 3};    // std::initializer_list<int>
auto single{42};          // int型
auto error{1, 2};         // エラー: 複数要素禁止

配列と関数

配列は通常ポインタに退化しますが、参照では完全な型を保持します:

char text[] = "C++";
auto arr1 = text;   // const char*
auto& arr2 = text;  // char (&)[4]

関数も同様の挙動を示します:

void sample(int);
auto func1 = sample;   // void (*)(int)
auto& func2 = sample; // void (&)(int)

条件式

条件式では共通の型に推論されます:

auto result = condition ? 10 : 3.14; // double型

タグ: C++11 auto 型推論 テンプレートメタプログラミング C++14

6月7日 20:08 投稿