在C ++中有没有办法做这样的事情?
union {
{
Scalar x, y;
}
Scalar v[2];
};
x == v[0]
和y == v[1]
的位置?
答案 0 :(得分:18)
由于您使用的是C ++而不是C,并且因为它们的类型相同,为什么不将x引用为v [0]而引用v [1]
答案 1 :(得分:14)
怎么样
union {
struct {
int x;
int y;
};
int v[2];
};
编辑:
union a {
struct b { int first, second; } bee;
int v[2];
};
丑陋,但更准确
答案 2 :(得分:6)
试试这个:
template<class T>
struct U1
{
U1();
T v[2];
T& x;
T& y;
};
template<class T>
U1<T>::U1()
:x(v[0])
,y(v[1])
{}
int main()
{
U1<int> data;
data.x = 1;
data.y = 2;
}
答案 3 :(得分:4)
之前我曾经使用过类似的东西。我不确定它的100%是否符合标准,但对于我需要使用它的任何编译器似乎都没问题。
struct Vec2
{
float x;
float y;
float& operator[](int i) { return *(&x+i); }
};
如果你想要(你可能应该想要),你可以向operator []添加边界检查等,你也可以提供const []的const版本。
答案 4 :(得分:1)
取决于“Scalar”是什么,是的,你可以用C ++做到这一点。语法几乎完全(可能甚至完全准确,但我在工会上生锈)你在你的例子中写的。它与C相同,除了对联合中可能存在的类型有限制(IIRC必须有默认构造函数)。这是相关的Wikipedia article。
答案 5 :(得分:1)
我一直在寻找类似的东西,并最终提出了解决方案。
我一直在寻找一个可以同时用作值数组和单个值的数据存储对象(以使最终用户灵活地编写Arduino库)。
这是我想出的:
xml_split
由于运算符的重载,我们可以像使用数组一样使用数据对象,并且可以将其用于函数调用中的传递引用(就像数组一样)!
如果有更多C ++经验的人有更好的方法来应用此最终产品,我希望看到它!
编辑:将代码更改为更加跨平台友好
答案 6 :(得分:1)
给出您的示例:
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
正如其他人指出的那样,通常,该标准不能保证x和y之间不会存在填充,实际上编译器在结构中插入填充是很常见的行为。
另一方面,采用以下解决方案:
struct U
{
int v[2];
int& x;
int& y;
};
U::U()
: x(v[0])
, y(v[1])
{}
我主要不喜欢的是我不得不提到x,y两次的事实。对于我不只几个元素(例如10)的情况,这变得不那么易读且难以维护。另外,U不再是 POD ,因为它需要用户定义的构造函数。最后,x&y引用会占用额外的内存。
因此,我想出的(对我来说可以接受的)折衷办法是:
struct Point
{
enum CoordType
{
X,
Y,
COUNT
};
int coords[CoordType::COUNT];
};
typedef Point::CoordType PtCoord;
您可以这样做:
Point p;
for ( int i = 0; i < PtCoord::COUNT; i++ )
p.coords[i] = 100;
std::cout << p.coords[PtCoord::X] << " " << p.coords[PtCoord::Y] << std::endl;
// 100 100
有点复杂,但我更喜欢引用建议。
答案 7 :(得分:1)
在C ++ 11中,您具有匿名的联合和结构,它们仅将其定义导出到封闭范围,因此您可以执行以下操作:
typedef int Scalar;
struct Vector
{
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
};