したがって、古い C ハッキングを使用するカスタム コンテナーを作成することを気にしない場合は、これを解決できます。
ここに例を書きました:
#include <iostream>
using namespace std;
struct ent
{
int myInt;
};
struct floats
{
float float1;
float float2;
};
struct container
{
bool isTypeFloats;
union
{
ent myEnt;
floats myFloats;
};
};
void main( void )
{
ent a = { 13 };
floats b = { 1.0f, 2.0f };
container c;
container d;
cout << b.float1 << " " << b.float2 << endl;
c.isTypeFloats = false;
c.myEnt = a;
d.isTypeFloats = true;
d.myFloats = b;
//correct accessor
if( c.isTypeFloats )
{
cout << c.myFloats.float1 << " " << c.myFloats.float2 << endl;
}
else
{
cout << c.myEnt.myInt << endl;
}
if( d.isTypeFloats )
{
cout << d.myFloats.float1 << " " << d.myFloats.float2 << endl;
}
else
{
cout << d.myEnt.myInt << endl;
}
}
これらの構造体をコンテナーに入れるには、次のようにします。std::vector< container >
これについて知っておくべきことがいくつかあります。
- ユニオンは最大の型にスペースを割り当てます。したがって、私の例では、int が 4 バイト、float が 4 バイトの場合、 を格納しているときでも に
ent
スペースが割り当てられるため、floats
を格納するたびに 4 バイトが無駄になりますent
。アプリケーションの目的と保存する型のサイズによっては、これは無視できる場合があります。
- 保存している型のサイズに大きな違いがある場合は、C++ が内部でユニオンを実際に処理している方法でこれを行うことができます。そして、それはを使用すること
void*
です。したがってstd::vector< void* > myVec
、次のように挿入します: myVec.push_back( &x )
where x
is your type, たとえばent
from our example. しかし、それを読むと、自分が何を指しているのかを知る必要があるため、次のようなことを行う必要があります。cout << ( ( ent* )myVec[0] )->myInt << endl;
事前定義された書き込みパターンがない限り、おそらくそれがどのタイプであるかがわからないため、おそらく次のようなコンテナー構造体を使用したくなるでしょう。
struct container2 { bool isTypeFloats; void* myUnion; }