型推論の基本規則
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型