是否调用 foo
在下面的代码中,导致UB?
using vec = std::array<int, 1>;
struct field0 {
vec data;
operator int() {
return data[0];
}
};
union a {
struct {
vec data;
} data;
field0 x;
};
void foo() {
a bar;
std::cin >> bar.data.data[0];
std::cout << bar.x;
}
根据标准。x
和 data
有相同的地址,所以应该可以安全地投下 this
到 vec*
. 还有: field0
和 vec
是布局兼容的,所以应该可以安全地检查 data
通过 x.data
或反之亦然。
然而,我们不仅要检查 x.data
的非静态成员函数,我们调用 x
在它的生命之外(还是我们?我找不到一个理由 x
终身应该开始了),所以形式上是UB。这样说对吗?
我想实现的是定义好的常见方法的版本,如命名数组领域的 union a { int data[3]; int x, y, z};
更新。
抱歉,在删除不必要的细节时,数组字段和 "getter "的布局兼容性丢失。现在恢复了。
我将需要使用 a
值的函数,以 int*
因此,在另一个方向上--声明字段并重载 operator[]
- 不是一个选项。
你的代码有未定义的行为。 初始公共序列规则在这里帮不了你,因为你不是在访问一个公共成员,而是在访问整个对象,以便调用成员函数1.
我试图实现的是一个定义良好的版本的普通方法来命名数组字段,如
union a { int data[3]; int x, y, z};
在C++中做到这一点的方法是使用一个结构和运算符重载。 与其拥有一个数组并试图将其映射到单个成员,不如拥有单个成员,然后假装你的类是一个数组。 这看起来像
struct vec
{
int x, y, z;
int& operator[](size_t index)
{
switch(index)
{
case 0: return x;
case 1: return y;
case 2: return z;
}
}
};
1:调用一个成员函数,就是把这个对象传递给该函数,好像它是函数的第一个参数。