std::variant
型安全なunionです
「std::variant」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。
型安全なユニオン
std::variantは、固定された型のリストからちょうど1つの値を保持し、どの型の値かを記憶します。使用するには<variant>をインクルードしてください。
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 10;
std::cout << std::get<int>(v) << "\n";
}異なる型の値を代入する
variantには、候補となっている任意の型の値を再代入できます。アクティブな候補も自動的に更新されます。
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 5;
v = 3.14; // now holds a double
std::cout << std::get<double>(v) << "\n";
}アクティブな型を確認する
std::holds_alternative<T>(v)は、variantが現在型Tの値を保持しているかどうかを示します。
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 2.0;
std::cout << std::holds_alternative<double>(v) << "\n";
std::cout << std::holds_alternative<int>(v) << "\n";
}index()関数
v.index()は、型のリストにおけるアクティブな型の0から始まる位置を返します。
#include <iostream>
#include <variant>
int main() {
std::variant<int, double, char> v = (char)65;
std::cout << v.index() << "\n"; // 2
}std::getによる安全なアクセス
std::get<T>はTがアクティブなら値を返し、そうでなければstd::bad_variant_accessを送出します。無言で無意味な値を返すことはありません。
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 7;
try {
std::cout << std::get<double>(v) << "\n";
} catch (const std::bad_variant_access& e) {
std::cout << "wrong type!\n";
}
}例外を送出しないget_if
std::get_if<T>(&v)は値へのポインターを返し、Tがアクティブでなければnullptrを返します。分岐を減らしたチェックに適しています。
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 9;
if (auto p = std::get_if<int>(&v))
std::cout << "int " << *p << "\n";
}デフォルト構築
デフォルト構築されたvariantは、最初の型を値初期化した値を保持します。最初の型が妥当なデフォルト値になるように、型の順序を決めてください。
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v; // holds int 0
std::cout << std::get<int>(v) << "\n";
}文字列を格納する
生のユニオンとは異なり、variantはstd::stringのような非自明な型も安全に保持できます。ライフタイムは自動的に管理されます。
#include <iostream>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> v = std::string("hello");
std::cout << std::get<std::string>(v) << "\n";
}戻り値の型としてのvariant
variantを返すことで、関数から複数の型のうち1つを返せます。呼び出し側はvariantを調べて、どの型の値が返されたかを確認します。
#include <iostream>
#include <string>
#include <variant>
std::variant<int, std::string> parse(bool ok) {
if (ok) return 42;
return std::string("error");
}
int main() {
auto r = parse(false);
if (auto s = std::get_if<std::string>(&r)) std::cout << *s << "\n";
}emplaceによるその場での変更
v.emplace<T>(args...)は、型Tの新しい値をvariantの内部に直接構築し、アクティブな候補を切り替えます。
#include <iostream>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> v = 1;
v.emplace<std::string>("switched");
std::cout << std::get<std::string>(v) << "\n";
}Variantを優先する理由
std::variantは、完全な型安全性を備えたユニオンのメモリ効率を提供します。アクティブな型を追跡し、ライフタイムを管理し、間違った型へのアクセスを拒否します。次のレッスンでは、これを処理する最もすっきりした方法を学びます。
理解度チェック
std::variantについての理解を確認しましょう。
まとめ
std::variantについて、次のことを学びました:
- 複数の型のうち1つを保持し、どの型かを追跡します。
holds_alternativeとindex()でアクティブな型を調べます。std::getは型が一致しないと例外を送出し、get_ifはポインターまたはnullを返します。std::stringのような非自明な型も安全に格納できます。
よくある質問
「std::variant」レッスンは無料ですか?
はい。「std::variant」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。
「std::variant」で何を学びますか?
型安全なunionです ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C++ Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「std::variant」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC++ Academyレッスンでコードを書いて実行できますか?
はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- スコープ付きenum class
- unionとそのリスク
- std::variant
- std::visit