プログラムにboost::Variantがあり、バリアント自体が初期化されているかどうか、またそのタイプの1つに値が含まれているかどうかを確認したいと思います。
バリアントでempty()を試しましたが、うまくいかないようです。NULLに対するチェックも行いません。
誰かがこれをチェックする方法を知っていますか?
編集:わかりました、それは決して空になることはないようですが、含まれているタイプに常に値があるとは限らないので、値のない状況を確認するにはどうすればよいですか?
決して空にならない保証と単一のストレージに関する私の質問を見ると、は、boost::variant
と呼ばれるNILのような値型をサポートしていboost::blank
ます。これにより、バリアントがヒープをバックアップストレージとして使用しないことが保証されます
boost::variant<>::which()
バインドされたバリアント型の整数インデックスを返すを使用して、どの型が格納されているかを検出できます。したがって、最初のタイプとして空白を使用する場合、which()は空白のときに0を返します
次の例を参照してください
typedef boost::variant< boost::blank , int , std::string > var_t;
var_t a;
assert( a.which() == 0 );
a = 18;
assert( a.which() == 1 );
お役に立てれば
Aboost::variant
は常に初期化されます。
明示的に初期化しなかった場合、最初のアイテムはデフォルトのコンストラクターを使用して構築されました。
struct Foo {};
struct Bar {};
struct Visitor: boost::static_visitor<>
{
void operator()(Foo const& foo) const { std::cout << "Foo\n"; }
void operator()(Bar const& bar) const { std::cout << "Bar\n"; }
};
int main(int argc, char* argv[])
{
boost::variant<Foo,Bar> var;
boost::apply_visitor(Visitor(), var); // prints Foo
return 0;
}
明確に定義されたバリアントがあることを確認する1つの方法は、バリアントリストに「NullType」を含めることです。それを使用するために作成する「ビジター」にさらにコードを記述する必要がある場合もありますが、例外をスローして、オペレーターに何かが間違っていることを知らせることができます。私は一般的にそのようなランタイムチェックに反対していますが、他の方法がない場合もあります。それを言うのに十分です:
class NullType{};
次に、それをバリアントリストの最初の引数として追加します。他の人が言っていて、ブーストのドキュメントに記載されているように、バリアントが空になる状況は決してありません。ただし、型チェックを実行して、関数をオーバーロードしない場合、または「NullType」がある場合にランタイム例外がスローされる場合に、「NullType」でコンパイルできないことを確認できます。
今あなたの変種:
boost::variant<NullType, int, double, long double> number;
class DoSomething : boost:static_visitor<void>{
public:
void visit(const int& _item);
void visit(const double& _item);
void visit(const long double& _item);
void visit(const NullType& _uhOh);
};
Boost.Variant には空でない保証があります。つまり、常に何らかの値を格納する必要があります。そのempty
メンバーは常に戻ることが保証されてfalse
おり、互換性のためにのみ存在します。
代わりにBoost.Anyをチェックしてみてください。
また、使用することができます
boost::variant<boost::blank, int, double, long double> number;
そしてバリアント機能empty()
。バリアントが常にその境界型の 1 つだけを含む場合、false を返します。(詳細については、決して空でない保証と呼ばれるセクションを参照してください。)