2010-05-14 48 views
2

我的问题是在代码中,但基本上我想知道如何/如果我可以做两条注释掉的线?我知道我可以在构造函数中完成,但我不想!如何初始化一个数组中的数组而不分别执行每个元素? (C++)

struct foo 
{ 
    int b[4]; 
} boo; 

//boo.b[] = {7, 6, 5, 4}; // <- why doesn't this work? (syntax error : ']') 
//boo.b = {7, 6, 5, 4}; // <- or else this? (syntax error : '{') 

boo.b[0] = 7; // <- doing it this way is annoying 
boo.b[1] = 6; // : 
boo.b[2] = 5; // : 
boo.b[3] = 4; // <- doing it this way is annoying 

boo.b[4] = 3; // <- why does this work! 

(使用:C++,Visual Studio 2005中)

+1

这是另一种场合,可以宣传即将推出的C++ 11标准的统一初始化语法...... – sbi 2010-05-14 15:51:08

回答

8

您只能使用初始化的定义:

struct foo 
{ 
    int b[4]; 
}; 
foo boo = { 7, 6, 5, 4 }; 

在最后一个问题: '为什么boo.b[4] = 3工作?'答案是它是未定义的行为,并且UB允许相当多的不同情况。编译器和运行时环境都不需要诊断它,并且在很多情况下,结果将覆盖内存中的下一个元素。这可能与下面的代码进行测试:

// Test 
foo boo; 
int x = 0; 
boo.b[4] = 5; 
std::cout << x << std::endl; 

注意:这是不确定的行为,因此无论该测试的结果是,这是不正确的,不能被认为是一个可重复的测试。

+0

更具体地说,引用超出数组边界的元素的能力是合法的。行为将取决于该内存位置是否属于另一个变量。所以在这种情况下,确切的行为是不确定的,因为'5'可能会或可能不会覆盖'x'的值。但是,如果你已经安排在结构的末尾分配额外的内存,那么这样的数组访问就没问题。因此,您有时可能会看到以1字节数组字段结尾的消息标头的结构定义,该字段实际上只是可变长度多字节数据的开头。 – 2010-05-14 16:12:27

1

如果你确实需要它被初始化后,写入该结构的成员,它看起来像你的价值观是遵循一个简单的模式(启动7和减量的一个),这意味着std::generate()std::generate_n()可以做的工作,太:

#include <algorithm> 
class DecrementFrom { 
     int val; 
public: 
     DecrementFrom(int start) : val(start) {} 
     int operator()() { return val--; } 
}; 

std::generate_n(foo.b, 4, DecrementFrom(7)); 
1

严格地说,用于初始化一个结构里的数组的语法是:

struct foo 
{ 
    int b[4]; 
}; 
foo boo = { { 7, 6, 5, 4 } }; 

但是,根据C标准的6.7.8.17,如果不提供它,编译器将隐式跟踪适当的范围。

相关问题