C++联合数组和变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/702658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ union array and vars?
提问by mpen
There's no way to do something like this, in C++ is there?
没有办法做这样的事情,在 C++ 中有吗?
union {
{
Scalar x, y;
}
Scalar v[2];
};
Where x == v[0]
and y == v[1]
?
哪里x == v[0]
和y == v[1]
?
回答by Brian R. Bondy
Since you are using C++ and not C, and since they are of the same types, why not just make x a reference to v[0] and y a reference to v[1]
既然您使用的是 C++ 而不是 C,而且它们的类型相同,为什么不只对 v[0] 进行 xa 引用,而对 v[1] 进行 ya 引用
回答by fido
How about
怎么样
union {
struct {
int x;
int y;
};
int v[2];
};
edit:
编辑:
union a {
struct b { int first, second; } bee;
int v[2];
};
Ugly, but that's more accurate
丑陋,但那更准确
回答by Martin York
Try this:
尝试这个:
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;
}
回答by Michael Anderson
I've used something like this before. I'm not sure its 100% OK by the standard, but it seems to be OK with any compilers I've needed to use it on.
我以前用过这样的东西。我不确定它的标准是否 100% OK,但是对于我需要使用它的任何编译器似乎都可以。
struct Vec2
{
float x;
float y;
float& operator[](int i) { return *(&x+i); }
};
You can add bounds checking etc to operator[] if you want ( you probably should want) and you can provide a const version of operator[] too.
如果您愿意(您可能应该想要),您可以向 operator[] 添加边界检查等,并且您也可以提供 operator[] 的 const 版本。
回答by Awbmilne
I was looking for a similair thing and eventually came up with a solution.
我正在寻找类似的东西,最终想出了一个解决方案。
I was looking to have a data storage object that I could use as both an array of values and as individual values (for end-user flexibility in writing Arduino libraries).
我希望有一个数据存储对象,我可以将它用作值数组和单个值(为了最终用户编写 Arduino 库的灵活性)。
Here is what I came up with:
这是我想出的:
class data{
union{
float _array[3];
struct{float _X, _Y, _Z;};
};
public:
float& X = _X;
float& Y = _Y;
float& Z = _Z;
float& operator[](int index){
if (index >= 3) return _array[0]; //Make this action whatever you want...
return _array[index];
}
float* operator&(){return _array;}
};
int main(){
data Test_Vector;
for(int i = 0; i < 3; i++){
Test_Vector = i;
}
cout<<"Member X = "<<Test_Vector.X;
cout<<"Member Y = "<<Test_Vector.Y;
cout<<"Member Z = "<<Test_Vector.Z;
float* vector_array = &Test_Vector;
cout<<"Array = {"<<vector_array[0]<<", "<<vector_array[1]<<", "<<vector_array[2]<<"}";
}
Thanks to Operator overloading, we can use the data object as if was an array and we can use it for pass-by-reference in function calls (just like an array)!
由于运算符重载,我们可以像使用数组一样使用数据对象,并且可以在函数调用中将其用于传递引用(就像数组一样)!
Note: Make sure to check on your system if this works due to the padding of structures.If someone with More C++ experience has a better cross-platform-friendly way of imitating my above code, I would love to see it!
注意:请确保检查您的系统是否由于结构填充而起作用。如果有更多 C++ 经验的人有更好的跨平台友好方式来模仿我上面的代码,我很乐意看到它!
回答by Zuzu Corneliu
Given your example:
鉴于你的例子:
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
As others have noted, in general, the standard does not guarantee that there will be no padding between x and y, and actually compilers inserting padding in structures is pretty common behavior.
正如其他人所指出的,一般来说,该标准不保证 x 和 y 之间没有填充,实际上编译器在结构中插入填充是非常常见的行为。
On the other hand, with solutions like:
另一方面,使用以下解决方案:
struct U
{
int v[2];
int& x;
int& y;
};
U::U()
: x(v[0])
, y(v[1])
{}
what I don't like mainly is the fact that I have to mention x, y twice. For cases where I have more than just a few elements (say 10), this becomes much less readable and harder to maintain. Additionally U can no longer be a PODsince it needs a user-defined constructor. And finally, the x & y references consume additional memory.
我不喜欢的主要是我不得不提到 x, y两次。对于我有多个元素(比如 10 个)的情况,这变得更不可读且更难维护。另外 U 不能再是一个POD,因为它需要一个用户定义的构造函数。最后,x & y 引用会消耗额外的内存。
Hence, the (acceptable for me) compromise I've come up with is:
因此,我提出的(对我来说可以接受的)妥协是:
struct Point
{
enum CoordType
{
X,
Y,
COUNT
};
int coords[CoordType::COUNT];
};
typedef Point::CoordType PtCoord;
With this you can then do:
有了这个,你可以这样做:
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
A bit sophisticated but I prefer this over the references suggestion.
有点复杂,但我更喜欢这个而不是参考建议。
回答by rmeador
Depending on what "Scalar" is, yes, you can do that in C++. The syntax is almost exactly (maybe even exactly exactly, but I'm rusty on unions) what you wrote in your example. It's the same as C, except there are restrictions on the types that can be in the unions (IIRC they must have a default constructor). Here's the relevant Wikipedia article.
根据“标量”是什么,是的,您可以在 C++ 中做到这一点。语法几乎与您在示例中所写的完全相同(甚至可能完全相同,但我对联合很生疏)。它与 C 相同,除了对联合中的类型有限制(IIRC 他们必须有一个默认构造函数)。这是相关的维基百科文章。