5

ユニオン内に含まれるオプションのPOD構造体があります。
boost::optional<>タイプを値で保持するので、これでうまくいくと思いました。

union helper
{
    int foo;
    struct 
    {
        char basic_info;
        struct details {
            //...
        };

        boost::optional<details> extended_info;
    } bar;
    //  ...
};

helper x = make_bar();

if( x.bar.extended_info )
{
    // use x.bar.extended_info->elements
}

しかし、VS2008は、要素が原因でbar構造体にコピーコンストラクターがあると不満を漏らしましたboost::optional<details>

代わりに、オプションのパラメーターが有効かどうかを示すブールフラグを追加しましたが、これは不格好です。

union helper
{
    int foo;
    struct 
    {
        char basic;
        struct details {
            bool valid;
            //...
        } extended;
    } bar;
    //  ...
};

details::operator bool()変数を返すように実装することを検討しましdetails::validたが、それはあいまいであり、人類に不利益をもたらします。
boost::optional<>構文と意図を明確に文書化し、探偵の仕事を必要としません。

最後に、helperユニオンはPODである必要があるため、動的な割り当てを行うことはできません。そうでない場合は、ポインターを使用します。

boost::optional<>ユニオンで使用できる構文的に類似したものについての提案はありますか?

4

2 に答える 2

13

非PODタイプをユニオンのフィールドとして使用することはできません。ユニオンの代わりに、C++でboost::variantなどを使用します。Cで記述されたモジュールとの互換性のためにのみunionを残します。

于 2011-01-12T20:58:02.800 に答える
0

他の人が述べているように、行うべき理想的なことは、からに変更することunionですboost::variant<>

ただし、これが不可能な場合は、boost::optional<>次のPOD近似を実装できます。

実装

template <typename T>
class Optional
{
    T value;
    bool valid;

public:

    // for the if(var) test
    operator bool() const  {  return valid;  }

    //  for assigning a value
    Optional<T> &operator=(T rhs)   
    {  
        value = rhs;  
        valid = true;  
        return *this;  
    }

    //  for assigning "empty"
    Optional<T> &operator=(void *)  
    {  
        valid = false;  
        return *this;  
    }

    // non-const accessors
    T &operator*()   {  return  value;  }
    T *operator->()  {  return &value;  }

    // const accessors
    const T &operator*()  const  {  return  value;  }
    const T *operator->() const  {  return &value;  }
};

のconstインスタンスを保持している場合は、constアクセサーが必要ですOptional<>

使用法

ポインタと同様に、Optional<T>デフォルトの状態はなく、信頼できるようになる前に初期化する必要があります(nullかどうか)。
とは異なりboost::optional<T>Optional<T>そのT値型から構築することはできず、別の。からのみ構築できますOptional<T>
構築時に値またはnullで初期化する場合は、。を使用してヘルパークラスを作成できますoperator Optional<T>()。私はそうしないことを選びました。

工事

Optional<details> additional_info;
Optional<details> more_info(additional_info);

割り当て

// if there's no additional info
additional_info = 0;

// if there is extended info
details x;
//  ...populate x...
additional_info = x;

データアクセス

if( extended_info )
{
    extended_info->member;
    // - or -
    details &info = *extended_info;
}

だから-それはそれほど悪くはなかった。それは私をそれほど暖かくてぼんやりと感じさせませんが、それは仕事を成し遂げます。

于 2011-01-13T20:33:32.203 に答える