C++17 の variant と union の比較 ― 2020年05月06日 12時30分36秒
まずは、variant 型と union 型の比較。
variant がたはテンプレートで受け付ける型を羅列していく。そのため、変数自体がどの型として処理をするかが推測される。
#include <variant>
#include <string>
#include <iostream>
int main()
{
std::variant< int, std::string > number1;
number1 = 3;
number1 = 3.14;
union number
{
int i;
double d;
} number2;
number2.i = 3;
number2.d = 3.14;
それに引き替えると、union 型は、型を指定して、そのアクセス方法も指定する。その為、variant 型に比べると冗長になってしまう。アクセス方法に名前を付けるので、同じ型を違う名前で指定できるのは、逆の立場としての利点には成り得る。
% c++ -std=c++17 variant_number.cpp
また、union は基本型しか指定できなかった。コンストラクタのある C++ オブジェクトはどの型が取られるかが決定できない。
それに引き替え、variant は型指定なので、C++ のオブジェクトが問題なく使えるようになっている。未初期化の場合は、一番最初の型がデフォルトになる。この例の場合、string 型を union に入れた部分のみがエラーになっている。
#include <variant>
#include <string>
int main()
{
std::variant< int, std::string > something;
something = 3;
something = "hello";
union int_str
{
int i;
std::string s;
} legacy;
legacy.i = 3;
legacy.s = "hello";
}
% c++ -std=c++17 variant_int_string.cpp
variant_int_string.cpp:14:7: error: call to implicitly-deleted default
constructor of 'union int_str'
} legacy;
^
variant_int_string.cpp:13:14: note: default constructor of 'int_str' is
implicitly deleted because variant field 's' has a non-trivial default
constructor
std::string s;
^
1 error generated.
最近のコメント