4

次のように定義されたType型のオブジェクトを返すgetterオブジェクトがあります。

typedef boost::variant<int, std::string> Empty;

返すintも文字列も持たず、代わりに空の状態を返す必要がある場合がよくあります。どうやってこの状態に戻ると思いますか?

a)typedef空のタイプをバリアントに追加します:boost::variant<int, std::string, Empty>

b)Type()を返す

c)例外をキャストする

d)boost :: shared_ptrを返します。これは、空の場合はNULLを指します。

4

3 に答える 3

8

正解は、boost::blank何も入れられないバリアントに使用することです。したがって、バリアント typedef は次のようになります。

typedef boost::variant<boost::blank, int, std::string> Empty;

blankはこのために特別に設計されてvariantおり、それに基づく特別なコードがあります。これを使用すると、コピー時にメモリ割り当てなしの保証が得られます (メンバーがコピー時に割り当てられない場合)。それでいいです。

バリアントは「空」になる可能性があるため、すべての処理ビジターがバリアントを処理できることが重要です。optionalや何かに基づいて多数の条件を設定するよりも、追加の訪問者経路を追加する方が便利なことがよくあります。さまざまなコード経路が訪問者に合わせてローカライズされます。これは多くの場合、optional<variant>.

于 2012-10-08T07:55:57.070 に答える
3

でラップしますboost::optional。これには、有効な値が割り当てられているかどうかを判断するための簡単なテスト (ブール値に変換可能) があります。その場合、バリアントを「空」状態で汚染する必要はありません。例えば

boost::optional<boost::variant<... > > some_func()
{
:
}

実際に何かを返す必要がある場合は、関数内でインプレース構造を使用することを忘れないでください。

于 2012-10-08T07:00:14.053 に答える
1

メソッドがオブジェクトを返すことができない可能性がある場合、これは一般的なアプローチです - メソッドをブール値にします:

bool get_value(Type& type) {
  if ( /*check variant emptyness*/) // one can use this - http://stackoverflow.com/a/7668530/670719
    return false;
  // else assign type 
}

ソリューションに関するコメント:

a) Empty を返す場合でも、メソッド呼び出しの後にチェックを行う必要があります。組み込みの bool が既にあるのに、なぜさらに型を追加するのでしょうか。

b) Type() は有効な変数と同じ値を持つことができます

c)例外は例外的なものですが、あなたの説明から「それはしばしば」です

d) あなたの問題は、Type を使用できず、同時に boost::variant を返すことができないことです。そのため、所有権の問題が追加されたタイプをもう 1 つ追加すると、クリーンなインターフェイスの最初の問題を解決せずに、何が起こっているのかについてさらに疑問が生じます。 .

于 2012-10-08T06:33:28.417 に答える