联盟中的boost :: optional <>?

msk*_*her 5 c++ boost optional-variables

我有一个可选的POD结构,它将包含在一个union中.
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
}
Run Code Online (Sandbox Code Playgroud)

但VS2008抱怨我的barstruct现在有一个复制构造函数,因为该boost::optional<details>元素.

作为替代,我添加了一个布尔标志来指示可选参数是否有效,但是它很笨重:

union helper
{
    int foo;
    struct 
    {
        char basic;
        struct details {
            bool valid;
            //...
        } extended;
    } bar;
    //  ...
};
Run Code Online (Sandbox Code Playgroud)

我考虑过实现details::operator bool()返回details::valid变量,但这是模糊不清的,也是对人类的伤害.
boost::optional<>清楚地记录语法和意图,不需要侦探工作.

最后,helperunion需要是POD,所以我不能做任何动态分配 - 否则我会使用指针.

对于在语法上与boost::optional<>联盟中可用的东西相似的东西的任何建议?

Öö *_*iib 13

您不能将非POD类型用作union中的字段.在C++中使用boost :: variant或类似的东西而不是union.保留union只是为了与用C编写的模块兼容.

  • 差不多这个 - 使用boost :: variant. (3认同)

msk*_*her 0

正如其他人提到的,理想的做法是将 a 更改union为 a boost::variant<>

但是,如果这不可能,您可以实现 POD 近似,boost::optional<>如下所示:

执行

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;  }
};
Run Code Online (Sandbox Code Playgroud)

如果您持有 的 const 实例,则 const 访问器是必需的Optional<>

用法

与指针一样,Optional<T>没有默认状态,并且必须在依赖它之前进行初始化(无论是否为空)。
与 不同boost::optional<T>Optional<T>不能从其值类型构造T,而只能从另一个 构造Optional<T>
如果您确实想在构造时对其进行值初始化或空初始化,则可以使用operator Optional<T>(). 我选择不这样做。

建造

Optional<details> additional_info;
Optional<details> more_info(additional_info);
Run Code Online (Sandbox Code Playgroud)

任务

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

// if there is extended info
details x;
//  ...populate x...
additional_info = x;
Run Code Online (Sandbox Code Playgroud)

数据存取

if( extended_info )
{
    extended_info->member;
    // - or -
    details &info = *extended_info;
}
Run Code Online (Sandbox Code Playgroud)

所以——结果并没有太糟糕。它并不让我感到很温暖和模糊,但它完成了工作。