gpt4 book ai didi

c++ - union 的平等比较?

转载 作者:搜寻专家 更新时间:2023-10-31 01:01:08 34 4
gpt4 key购买 nike

在 C 和/或 C++ 中是否有标准(或至少安全)的方法来比较 union 的相等性?我希望按位比较在许多情况下都会有用,不管每个 union 中最后分配的成员;例如,可以保留一个特定的位模式来表示“值未初始化”,并且能够检查 union 是否未初始化而无需指定“事件”成员将很有用。

C++ 中的一个例子(虽然我认为这个概念扩展到使用非成员函数的 C):

union MyData
{
public:
// Assume I'm compiling this on a platform where the size of `int`
// exceeds the size of `char*`, or that I'm using some combination
// if `#ifdef`s or similar to ensure that my numeric type is sufficiently
// large, or that I include an extra member that is known to be
// exactly the size of the larger member, just for the sake of
// comparison.
int int_member;
char* ptr_member;

bool isInitialized() const
{
return (*this != INVALID_VAL);
}

bool operator==(MyData const& rhs)
{
return / * ??? */;
}

private:
constexpr MyData INVALID_VAL { /* ??? */ };
}

// ... later, in client code...

MyData d;
bool initialized{d.isInitialized()}; // false
d.ptr_member = new char[32];
bool initialized{d.isInitialized()}; // true

这里,INVALID_VAL 可以通过将 int_member 设置为最大负整数值来定义,因为这是一个不均匀的值,所以它不会在单词边界上因此极不可能分配给 char* 成员(假设分配通常直接来自 new)。

operator== 的一种可能实现方式很简单:

return int_member == rhs.int_member;

尽管不知道 int_member 是否是“活跃”成员,但我希望这是安全的,因为我看不出为什么要从 char* 进行静态转换到 int 应该失败或有问题。对吗?

如果这个实现不安全的,像下面这样的事情应该是可能的(当然在 C 中使用 C 风格的转换):

return static_cast<void*>(*this) == static_cast<void*>(rhs);

...当然,如果 MyData 大于指针的大小,您就必须开始使用 sizeof 来解决这个问题。

有人这样做吗?第一个(更简单的)实现安全吗?有什么理由这样做吗?

最佳答案

我认为更好的方法是将您的 union 包装在一个类或结构中,并使用枚举字段存储最后访问的成员,例如

class MyData {
enum {
unintialized, int_member, ptr_member
} last_member = unintialized;

union {
int int_member;
char* ptr_member;
} union_fields;

public:
bool isInitialized() const
{
return last_member != unintialized;
}
};

如果你有 C++11,last_member 的类内初始化是有效的,否则只需在默认构造函数中初始化它。

为这两个字段创建访问器并相应地设置last_member,最好在访问器方法中添加检查以确保只能访问“事件成员”。

关于c++ - union 的平等比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29702754/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com