1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C++】std::variantの使い方とunionとの違い

1
Posted at

C++17で導入されたstd::variantは、
複数の型のうちどれか1つを安全に保持できる型安全な共用体です。

本記事では、std::variantの基本的な使い方を紹介したいと思います。

前提知識

  • C++の基礎構文を理解している

std::variantとは

std::variantは、C++17 で導入された 複数の型のうちどれか1つを保持できる型安全な共用体です。

従来のunionと違い、std::variantは現在どの型が入っているかを自動で管理し、非トリビアル型(std::string など、メモリをそのままコピーするとダメな型)も安全に扱えます。

サンプルコード

main.cpp
//-----------------------------------------------------------------
//! @file   main.cpp
//! @brief  std::variantの使い方サンプル
//! @author つきの
//-----------------------------------------------------------------
#include <iostream>
#include <variant>
#include <string>

//-----------------------------------------------------------------
//! @class A
//! @brief Draw() メソッドを持つクラス A
//-----------------------------------------------------------------
struct A {
	//-----------------------------------------------------------------
	//! @brief Draw() メソッド
	//-----------------------------------------------------------------
	void Draw() const {
		std::cout << "A::Draw()" << std::endl;
	}
};

//-----------------------------------------------------------------
//! @class B
//! @brief Draw() メソッドを持つクラス B
//-----------------------------------------------------------------
struct B {
	//-----------------------------------------------------------------
	//! @brief Draw() メソッド
	//-----------------------------------------------------------------
	void Draw() const {
		std::cout << "B::Draw()" << std::endl;
	}
};

// エントリポイント
int main() {
	// A または B のどちらかを保持できる variant
	std::variant<A, B> v;

	v = A{}; // A を入れる

	// 現在入っている型に応じて Draw() を呼び分ける
	std::visit([](auto& x) {
		x.Draw();
		}, v);

	v = B{}; // B を入れる

	std::visit([](auto& x) {
		x.Draw();
		}, v);

	return 0;
}

宣言

宣言時は、テンプレートに保持したい型を記述します。

main.cpp
    // A または B のどちらかを保持できる variant
	std::variant<A, B> v;

代入

入れたい型を代入するだけで代入可能です。
代入するだけで自動で型が入れ替わります。

main.cpp
	v = A{}; // A を入れる

メンバ関数を使用したい場合

std::visitを使用することで、メンバ関数を使用することが出来ます。

main
	// 現在入っている型に応じて Draw() を呼び分ける
	std::visit([](auto& x) {
		x.Draw();
		}, v);

総括

  • std::variantを使用することで、複数の型の中から一つの値をを同じ変数で保持することが出来る

  • メンバ関数を使用したい場合はstd::visitを使用する

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?