「Cpp 型推論 auto」の版間の差分
188行目: | 188行目: | ||
この他、ラテラルによる型推論もあります。[[Cpp 文字列リテラル|リテラルの記事]]も理解するといいと思います。 | この他、ラテラルによる型推論もあります。[[Cpp 文字列リテラル|リテラルの記事]]も理解するといいと思います。 | ||
[[C PlusPlus#C++からの技術|C++]]に戻る | [[C PlusPlus#C++からの技術|C++]]に戻る |
2024年1月30日 (火) 13:07時点における最新版
C++に戻る
本来の表記は「C++(Cpp) 型推論 auto」です。この記事に付けられた題名はテンプレート:記事名の制約から不正確なものとなっています。 |
※このページではC++にのみ存在する機能として、記事タイトルがC++ 型推論 autoになっています。
型推論 auto
C++11から導入されたautoによる型推論は、変数宣言時に具体的な型名の代わりにautoキーワードを指定することで、変数の型を初期化子から推論できるようになりました。例えば、以下のように、int型の変数iを初期化子0で初期化する場合、autoキーワードを使って、変数の型を推論することができます。
auto i = 0; // iはint型
autoキーワードは、配列や標準ライブラリのコンテナ、ユーザー定義のクラスに対しても使用することができます。また、autoキーワードは、関数の戻り値の型を後置する関数宣言構文でも使用されますが、その場合のautoには型推論の意味はありません。
C++の型推論による初期化子の種類は、主に以下のものがあります。
直接初期化 (Direct Initialization):
cpp
auto x = 42; // int型
auto y = 3.14; // double型
auto z = "Hello, World!"; // const char[14]型
コピー初期化 (Copy Initialization):
cpp
auto a = 42; // int型
auto b = 3.14; // double型
auto c = "Hello, World!"; // const char[14]型
リスト初期化 (List Initialization):
cpp
auto arr = {1, 2, 3}; // std::initializer_list<int>型
auto vec = std::vector<int>{1, 2, 3}; // std::vector<int>型
auto lst = {1, 3.14, "Hello"}; // std::initializer_list<std::variant<int, double, const char*>>型
参照の初期化 (Reference Initialization):
cpp
int i = 42;
auto& ref_i = i; // int&型
const double pi = 3.14;
auto& ref_pi = pi; // const double&型
const char* str = "Hello";
auto& ref_str = str; // const char*&型
右辺値参照の初期化 (Rvalue Reference Initialization):
cpp
int a = 42;
auto&& rvalue_ref = std::move(a); // int&&型
これらの初期化子を使った際に、autoキーワードを使用することで型推論が行われます。型推論は、初期化子の種類によって微妙に異なる場合があります。一般的には、直接初期化やコピー初期化の場合は初期化子の型と同じ型になりますが、リスト初期化の場合や参照の初期化の場合は注意が必要です。
例えば、リスト初期化の場合は初期化子の型を見て適切な型が選ばれます。参照の初期化の場合は、参照先の型になります。
注意: autoによる型推論が明示的な型指定よりも柔軟である一方で、適切な型が推論されない場合やプログラマの意図しない型が推論される可能性もあるため、慎重に使用する必要があります。
例えば、以下のような型として推論されることがあります。実に様々ですが10パターンをあげます。
ポインタ型:
cpp
int x = 42;
auto ptr = &x; // int*型
参照型:
cpp
int y = 42;
auto& ref = y; // int&型
配列型:
cpp
int arr[] = {1, 2, 3};
auto arr_auto = arr; // int[3]型
関数ポインタ型:
cpp
int add(int a, int b) { return a + b; }
auto func_ptr = &add; // int (*)(int, int)型
メンバポインタ型:
cpp
struct MyStruct {
int member;
};
auto member_ptr = &MyStruct::member; // int MyStruct::*型
クラス型:
cpp
class MyClass {
// ...
};
auto obj = MyClass(); // MyClass型
enum型:
cpp
enum Color { Red, Green, Blue };
auto color_enum = Color::Red; // Color型
nullptr型:
cpp
auto null_ptr = nullptr; // std::nullptr_t型
decltype型:
cpp
int z = 42;
decltype(z) decl_z = 10; // int型
テンプレート型:
cpp
template <typename T>
T add(T a, T b) { return a + b; }
auto result = add(3, 4); // int型
この他、ラテラルによる型推論もあります。リテラルの記事も理解するといいと思います。
C++に戻る