向量之间的转换是否定义了行为?

Is conversion between vectors defined behavior?

为了在我的游戏中序列化组件,我需要能够访问各种向量中的数据,只需给定一个指针和向量的大小。

如果我只有一个 void * 指向向量,我想从向量中获取 data() 指针。我正在尝试从 std::vector<T> 转换为 std::vector<char> 以获取 data() 指针。我想知道下面的代码是否定义了行为并且在不同情况下不会有任何不同的行为。

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> ints = { 0, 1, 2, 3, 4 };

    std::vector<char>* memory = reinterpret_cast<std::vector<char>*>(&ints);
    int *intArray = reinterpret_cast<int *>(memory->data());

    std::cout << intArray[0] << intArray[1] << intArray[2] << intArray[3] << intArray[4] << std::endl; //01234 Works on gcc and vc++
    std::getchar();
}

这似乎在这个孤立的案例中有效,但我不知道它是否会在序列化代码中产生错误或未定义的行为。

这是一个混叠违规:

std::vector<char>* memory = reinterpret_cast<std::vector<char>*>(&ints);
int *intArray = reinterpret_cast<int *>(memory->data());

根据 [basic.life],在此处访问 memory->data() 具有未定义的行为。

解决这个问题的方法是调用 ints.data() 以获得指向底层连续数组的 int* 指针。之后,您可以将其转换为 void*char*unsigned char*(或 C++17 中的 std::byte*)。

从那里您可以转换回 int* 以再次访问元素。

我不认为它是 UB。

使用 reinterpret_cast<std::vector<char>*>(&ints),您将一个矢量对象转换为另一个不同(实际上不兼容)类型的矢量对象。然而,您没有取消引用结果指针,并且 - 由于两个矢量对象很可能具有相同的别名限制 - 转换将没问题。比方说this在线C++草稿)。请注意,向量不存储数据类型 "in place",但会保存指向值的指针。

5.2.10 Reinterpret cast

(7) An object pointer can be explicitly converted to an object pointer of a different type.70 When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast(static_cast(v)) if both T1 and T2 are standard-layout types ([basic.types]) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.

因此,前后投射矢量对象应该以定义的方式工作。

其次,您将最初指向(并别名指向)int "back" 的指针转换为其原始类型 int。所以显然没有违反别名。

我在这里没有看到任何 UB(除非矢量对象具有比矢量对象更严格的别名规则,但很可能不是这种情况)。