当这些对象具有相同的二进制表示时,“reinterpret_cast”两个不相关的对象向量是否安全?

Rob*_*bin 3 c++ casting

我有围绕 int 的新类型,以及包含这些新类型的类。

class IndexA {
    int i;
};
class A {
    IndexA index;
};

// this mimic exactly the hierarchy of `A`
struct IndexB {
    int i;
};
struct B {
    IndexB index;
};
Run Code Online (Sandbox Code Playgroud)

鉴于此AB共享完全相同的二进制布局,以下代码是否包含未定义的行为还是安全?

std::vector<A> vfoo {...};
std::vector<B> vbar {
    std::move(
        reinterpret_cast<std::vector<B>&>(vfoo)
    )
};
Run Code Online (Sandbox Code Playgroud)

我本来希望能够从做一个零拷贝的举动转变std::vector<A>std::vector<B>。是否可以?

在我的代码中:

  • A并且B实际上只是围绕 的包装器int,因此它们具有完全相同的二进制表示形式。
  • 该结构A只包含一个组合IndexAstd::optional<IndexA>std::variant<IndexA, other types like IndexA>,或std::vector<IndexA or std::optional<IndexA>, …>。我认为我可以假设它们具有相同的表示形式。
  • B是 的严格副本A,其中 的每个实例IndexA都替换为IndexB。字段顺序被保留。

eer*_*ika 6

reinterpret_cast当这些对象具有相同的二进制表示时,两个不相关的对象向量是否安全?

不,这不安全。示例程序的行为未定义。

我本来希望能够从做一个零拷贝的举动转变std::vector<A>std::vector<B>。是否可以?

不,这是不可能的。


您可以做的并且与您正在尝试的有点接近的事情是拥有这些类型的联合向量:

union IndexAB {
    IndexA A;
    IndexB B;
};

std::vector<IndexAB> vfoo {...};
for (IndexAB& u : vfoo) {
    std::cout << u.A.i;
    u.B.i = 42;
}
Run Code Online (Sandbox Code Playgroud)

AB工会成员是否被激活并不重要。无论如何,我们都可以访问任何一个成员。

请注意,这通常不适用于所有联合,而仅适用于标准布局结构的这种特殊情况,特别是它们共同初始序列中的成员。