c ++使用数组作为成员初始化结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2650374/
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++ Initializing a struct with an array as a member
提问by Drew Shafer
Edited again because it originally wasn't clear that I'm trying to initialize the arrays at compile time, not at run time...
再次编辑,因为最初不清楚我试图在编译时初始化数组,而不是在运行时...
I've got the following reduced testcase:
我有以下简化的测试用例:
typedef struct TestStruct
{
int length;
int values[];
};
TestStruct t = {3, {0, 1, 2}};
TestStruct t2 = {4, {0, 1, 2, 3}};
int main()
{
return(0);
}
This works with Visual C++, but doesn't compile with g++ under linux. Can anyone help me make this specific kind of initializer portable?
这适用于 Visual C++,但不能在 linux 下使用 g++ 编译。任何人都可以帮助我使这种特定类型的初始化程序可移植吗?
Additional details: the actual structure I'm working with has several other int values, and the array can range in length from a single entry to over 1800 entries.
其他详细信息:我正在使用的实际结构有几个其他 int 值,数组的长度范围可以从单个条目到超过 1800 个条目。
EDIT: I think (but am not sure) that this is not a VLA issue. To clarify, I'm trying to get the compiler to do the work for me at compile-time. The length of the array at run-time is constant. Apologies if I'm wrong; I'm primarily a c#/Perl/Ruby programmer who is stuck maintaining this legacy app...
编辑:我认为(但不确定)这不是 VLA 问题。澄清一下,我试图让编译器在编译时为我做这项工作。运行时数组的长度是恒定的。如果我错了,请道歉;我主要是 ac#/Perl/Ruby 程序员,他们一直在维护这个遗留应用程序......
Any help much appreciated. Thanks!
非常感谢任何帮助。谢谢!
回答by Evan Teran
c++ doesn't have the same flexible array member as last element as c99. You should use a std::vector
if you don't know how many elements or you should specify how many if you do.
c++ 没有与 c99 相同的灵活数组成员作为最后一个元素。std::vector
如果您不知道有多少个元素,您应该使用 a,或者如果您知道,则应该指定多少个。
EDIT:You have said in your edit that the array is a runtime constant, so specify the size and it should work fine. g++ has no problem with the following code:
编辑:您在编辑中说过该数组是一个运行时常量,因此请指定大小,它应该可以正常工作。g++ 没有问题,下面的代码:
struct TestStruct { // note typedef is not needed */
int length;
int values[3]; // specified the size
};
TestStruct t = {3, {0, 1, 2}};
int main() {
// main implicitly returns 0 if none specified
}
EDIT:to address your comment, you could use templates like this:
编辑:为了解决您的评论,您可以使用这样的模板:
template <int N>
struct TestStruct {
int length;
int values[N];
};
TestStruct<3> t3 = {3, {0, 1, 2}};
TestStruct<2> t2 = {2, {0, 1}};
int main() {}
The only problem is that there is no easy way to put both t2 and t3 in a container (like a list/vector/stack/queue/etc because they have different sizes. If you want that, you should use std::vector
. Also, if you are doing that, then it isn't necessary to store the size (it is associated with the type). So you could do this instead:
唯一的问题是没有简单的方法将 t2 和 t3 都放在一个容器中(比如列表/向量/堆栈/队列/等,因为它们有不同的大小。如果你想要,你应该使用std::vector
。另外,如果你这样做,那么就没有必要存储大小(它与类型相关联)。所以你可以这样做:
template <int N>
struct TestStruct {
static const int length = N;
int values[N];
};
TestStruct<3> t3 = {{0, 1, 2}};
TestStruct<2> t2 = {{0, 1}};
int main() {}
But once again, you cannot put t2 and t3 in a "collection" together easily.
但是再一次,您不能轻易地将 t2 和 t3 放在一个“集合”中。
EDIT:All in all, it sounds like you (unless you store more data than just some numbers and the size) don't need a struct at all, and can't just use a plain old vector.
编辑:总而言之,听起来您(除非您存储的数据不仅仅是一些数字和大小)根本不需要结构,并且不能只使用普通的旧向量。
typedef std::vector<int> TestStruct;
int t2_init[] = { 0, 1, 2 };
TestStruct t3(t3_init, t3_init + 3);
int t2_init[] = { 0, 1 };
TestStruct t2(t2_init, t2_init + 2);
int main() {}
Which would allow you to have both t2 and t3 in a collection together. Unfortunately std::vector
doesn't (yet) have array style initializer syntax, so i've used a shortcut. But it's simple enough to write a function to populate the vectors in a nice fashion.
这将允许您将 t2 和 t3 放在一个集合中。不幸的std::vector
是(还)没有数组样式的初始化语法,所以我使用了一个快捷方式。但是编写一个函数来以一种很好的方式填充向量是很简单的。
EDIT:OK, so you don't need a collection, but you need to pass it to a function, you can use templates for that to preserve type safety!
编辑:好的,所以你不需要一个集合,但你需要将它传递给一个函数,你可以使用模板来保持类型安全!
template <int N>
struct TestStruct {
static const int length = N;
int values[N];
};
TestStruct<3> t3 = {{0, 1, 2}};
TestStruct<2> t2 = {{0, 1}};
template <int N>
void func(const TestStruct<N> &ts) { /* you could make it non-const if you need it to modify the ts */
for(int i = 0; i < N; ++i) { /* we could also use ts.length instead of N here */
std::cout << ts.values[i] << std::endl;
}
}
// this will work too...
template <class T>
void func2(const T &ts) {
for(int i = 0; i < ts.length; ++i) {
std::cout << ts.values[i] << std::endl;
}
}
int main() {
func(t2);
func(t3);
func2(t2);
}
回答by zufuliu
GCC/Clang support the following extension
GCC/Clang 支持以下扩展
typedef struct TestStruct { int length; int* values; }; TestStruct t = {3, (int[]){0, 1, 2}}; TestStruct t2 = {4, (int[]){0, 1, 2, 3}};
回答by aGuegu
struct TestStruct {
int length;
const int *values;
};
static const uint8_t TEST_STRUCT_VAL_1[] = {0, 1, 2};
const TestStruct t1 = {3, TEST_STRUCT_VAL_1};
static const uint8_t TEST_STRUCT_VAL_2[] = {0, 1, 2, 3};
const TestStruct t2 = {4, TEST_STRUCT_VAL_2};`
In my case, stm32 programming with gcc/g++, the value array is only raw data storage, so it is static const, and would be stored in flash. I use this way to store font patterns for lcd display.
在我的例子中,stm32 使用 gcc/g++ 编程,值数组只是原始数据存储,所以它是静态常量,将存储在闪存中。我用这种方式来存储液晶显示器的字体模式。
using template is typing saving, but not size saving.
使用模板是打字保存,但不是大小保存。
回答by tristan
VLAis only supported in C99. C++ doesn't support that. From http://gcc.gnu.org/c99status.html, gcc supports VLA now.
VLA仅在 C99 中受支持。C++ 不支持。从http://gcc.gnu.org/c99status.html 开始,gcc 现在支持 VLA。