gpt4 book ai didi

c++ - 在不同限定的结构成员上使用 reinterpret_cast 是否安全?

转载 作者:可可西里 更新时间:2023-11-01 18:31:25 25 4
gpt4 key购买 nike

我查看了以下相关的问题,但似乎没有一个能解决我的确切问题:one , two , three .

我正在编写一个集合,其中的元素(键值对)与一些簿记信息一起存储:

struct Element {
Key key;
Value value;
int flags;
};

std::vector<Element> elements;

(为简单起见,假设 KeyValue 都是标准布局类型。该集合无论如何都不会与任何其他类型一起使用。)

为了支持基于迭代器的访问,我编写了覆盖 operator->operator* 的迭代器,以向用户返回一个指针和一个引用,分别为键值对。但是,由于集合的性质,永远不允许用户更改返回的 key 。为此,我声明了一个 KeyValuePair 结构:

struct KeyValuePair {
const Key key;
Value value;
};

我在迭代器上实现了 operator->,如下所示:

struct iterator {
size_t index;

KeyValuePair *operator->() {
return reinterpret_cast<KeyValuePair *>(&elements[index]);
}
};

我的问题是:reinterpret_cast 的这种使用是定义明确的,还是调用了未定义的行为?我试图解释标准的相关部分并检查了有关类似问题的问题的答案,但是,我未能从中得出明确的结论,因为……:

  • 这两种结构类型共享一些初始数据成员(即 keyvalue),仅在 const 限定上有所不同;<
  • 标准没有明确说明 Tcv T 是布局兼容的,但也没有相反的说明;此外,它还规定它们应具有相同的表示和对齐要求;
  • 如果第一个但许多成员具有布局兼容类型,则两个标准布局类类型共享一个公共(public)初始序列;
  • 对于包含共享公共(public)初始序列的类类型成员的 union 类型,允许使用任一 union 成员​​ (9.2p18) 检查此类初始序列的成员。– 对于共享公共(public)初始序列的reinterpret_casted pointers-to-structs 没有类似的明确保证。– 但是,保证指向结构的指针指向其初始成员 (9.2p19)。

仅使用这些信息,我发现无法推断出 ElementKeyValuePair 结构是否共享一个公共(public)初始序列,或者是否有任何其他共同点可以证明我的观点重新解释_cast

顺便说一句,如果您认为为此目的使用 reinterpret_cast 是不合适的,而且我确实面临 XY 问题,因此我应该简单地做一些其他事情来实现我的目标,请告诉我.

最佳答案

My question is: is this use of reinterpret_cast well-defined, or does it invoke undefined behavior?

reinterpret_cast 在这里是错误的方法,您只是违反了严格的别名。 reinterpret_castunion 在这里 fork 有点令人费解,但是这个场景的措辞非常清楚。

这样简单地定义 union 可能会更好:

union elem_t {
Element e{}; KeyValuePair p;
/* special member functions defined if necessary */
};

... 并将其用作 vector 元素类型。请注意,在确定布局兼容性时忽略 cv 限定 - [basic.types]/11:

Two types cv1 T1 and cv2 T2 are layout-compatible types if T1 and T2 are the same type, […]

因此 ElementKeyValuePair 确实共享一个公共(public)初始序列,并访问 p 的相应成员,前提是 e 是活的,是明确定义的。


另一种方法:定义

struct KeyValuePair {
Key key;
mutable Value value;
};

struct Element : KeyValuePair {
int flags;
};

现在提供一个迭代器,它简单地从 vector 中包装一个 const_iterator 并向上转换要公开的引用/指针。 key 不可修改,但 value 可以。

关于c++ - 在不同限定的结构成员上使用 reinterpret_cast 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33312291/

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