升压::可选<>在工会?

发布于 2024-10-11 13:46:35 字数 1272 浏览 1 评论 0 原文

我有一个可选的 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

元素而有一个复制构造函数

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

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

我考虑实现 details::operator bool() 来返回 details:: valid 变量,但这很晦涩并且对人类有害。
boost::Optional<> 清楚地记录了语法和意图,并且不需要侦探工作。

最后,helper 联合需要是 POD,因此我无法进行任何动态分配 - 否则我会使用指针。

对于语法上类似于可在联合中使用的 boost::Optional<> 的东西有什么建议吗?

I have an optional POD struct that will be contained inside a union.
boost::optional<> holds its type by value, so I thought this could work:

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
}

but VS2008 complained that my bar struct now had a copy constructor due to the boost::optional<details> element.

As a replacement, I've added a boolean flag to indicate whether the optional parameter is valid, but it's clunky:

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

I considered implementing details::operator bool() to return the details::valid variable, but that's obscure and a disservice to humanity.
boost::optional<> clearly documents the syntax and intent and doesn't require detective work.

Finally, the helper union needs to be POD, so I can't do any dynamic allocation - otherwise I would use a pointer.

Any suggestions for something syntactically similar to boost::optional<> that's usable in a union?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生一个溪 2024-10-18 13:46:35

您不能使用非 POD 类型作为 union 中的字段。在 C++ 中使用 boost::variant 或类似的东西代替 union。保留联合仅是为了与用 C 编写的模块兼容。

You can not use non-POD types as fields in union. Use boost::variant or something like it in C++ instead of union. Leave union only for compatibility with modules written in C.

妄司 2024-10-18 13:46:35

正如其他人所提到的,理想的做法是将 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 没有默认状态,必须先进行初始化,然后才能依赖它(无论是否为 null)。
boost::Optional 不同,Optional 不能从其 T 值类型构造,而只能从另一个值类型构造可选
如果您确实想在构造时对其进行值初始化或空初始化,则可以使用操作符Optional()创建一个辅助类。我选择不这样做。

施工

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;
}

所以 - 事实证明这并不算太糟糕。它并不让我感到很温暖和模糊,但它完成了工作。

As others have mentioned, the ideal thing to do is to change from a union to a boost::variant<>.

However, if this isn't possible, you can implement a POD approximation of boost::optional<> as follows:

Implementation

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;  }
};

The const accessors are necessary if you are holding a const instance of Optional<>.

Usage

Like a pointer, Optional<T> has no default state and must be initialized before you can rely on it (null or not).
Unlike boost::optional<T>, Optional<T> cannot be constructed from its T value type, and can only be constructed from another Optional<T>.
If you really want to value- or null-initialize it at construction, you could make a helper class with an operator Optional<T>(). I chose not to.

Construction

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

Assignment

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

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

Data access

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

So - it didn't turn out to be too bad. It doesn't make me feel quite warm and fuzzy, but it gets the job done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文