c++以数组作为成员初始化结构

标签 c++ struct initialization portability

再次编辑是因为最初并不清楚我是在编译时而不是在运行时初始化数组...


我有以下简化的测试用例:

typedef struct TestStruct
{
    int length;
    int values[];
};

TestStruct t = {3, {0, 1, 2}};
TestStruct t2 = {4, {0, 1, 2, 3}};

int main()
{
    return(0);
}

这适用于 Visual C++,但不能在 linux 下使用 g++ 编译。谁能帮我把这种特定的初始化程序做成可移植的?

其他细节:我正在使用的实际结构有几个其他 int 值,并且数组的长度范围可以从单个条目到超过 1800 个条目。

编辑:我认为(但不确定)这不是 VLA 问题。为了澄清,我试图让编译器在编译时为我完成工作。运行时数组的长度是恒定的。如果我错了,请道歉;我主要是一名 c#/Perl/Ruby 程序员,一直在维护这个遗留应用程序......

非常感谢任何帮助。谢谢!

最佳答案

c++ 没有与 c99 中最后一个元素相同的灵活数组成员。如果你不知道有多少元素,你应该使用 std::vector,如果你知道,你应该指定多少。

编辑:您在编辑中说过该数组是运行时常量,因此请指定大小,它应该可以正常工作。 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
}

编辑:要解决您的评论,您可以使用这样的模板:

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() {}

唯一的问题是没有简单的方法将 t2 和 t3 放在一个容器中(比如列表/vector/堆栈/队列/等,因为它们有不同的大小。如果你想要这样,你应该使用 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() {}

但是再一次,你不能轻易地将 t2 和 t3 放在一个“集合”中。

编辑: 总而言之,听起来您(除非您存储的数据不仅仅是一些数字和大小)根本不需要结构,也不能只使用普通的旧 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() {}

这将允许您将 t2 和 t3 放在一个集合中。不幸的是 std::vector (还)没有数组样式初始化语法,所以我使用了快捷方式。但是编写一个函数来以一种很好的方式填充 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}};

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);
}

关于c++以数组作为成员初始化结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2650374/

相关文章:

c++ - GDB 中内部类的不完整类型,其虚拟方法在单独的文件中定义

c - 结构体和结构体指针之间的区别

c - 为什么 printf 无法打印 Jack 和 George 的名字?

c++ - 专用模板类的静态成员初始化

c++ - 函数样式转换与调用构造函数

javascript - 将回调作为参数发送给 QJSValue::callAsConstructor()

c++ - 每次循环迭代时清理 vector 。最有效的内存方式是什么?

c - 释放指针重新分配自身?

c++ - 声明和初始化struct类型变量时出错

c++ - 复制初始化的奇怪行为,不调用复制构造函数!