3

给定

std::vector<CMyClass> objects;
CMyClass list[MAX_OBJECT_COUNT];

这样做是否明智?

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i++));

或者我应该将我的循环扩展到这个?

for(unsigned int i = 0; i < objects.size(); i++)
{
  list[i] = objects.at(i);
}
4

4 回答 4

11

前者是未定义的行为。未指定是否list[i]在函数调用之前或之后评估(为赋值的 lhs 提供左值)objects.at

因此,表达式的各个部分有一个合​​法的顺序,其中i被访问 (in list[i]) 和单独修改 (in i++),没有中间的序列点。

这正是 C++ 标准中未定义行为的条件——是否存在这样的合法顺序。IIRC C 标准的表达方式略有不同,但效果相同。

如果有疑问,不要编写使用自增运算符的表达式,并且在表达式的其他任何地方也使用相同的值。您可以使用逗号运算符(i++, i++很好)和条件运算符(i ? i++ : i--很好)来做到这一点,因为它们中有序列点,但这很少值得。||同样,类似的&&事情p != end_p && *(p++) = something;并非完全不可信。任何其他用途,如果你盯着它看足够长的时间,你通常可以制定出一个把事情搞砸的评估顺序。

除了复杂的for表达式和for空体循环的可理解性之外。

于 2010-03-29T14:26:26.913 回答
6

如有疑问,请选择更易于理解的形式(展开循环)。

(而且我认为list[i] = objects.at(i++)会导致未定义的行为。)

于 2010-03-29T14:23:24.500 回答
1

i在相同的表达式中引用i++可能是未定义的行为。但既然看起来你正在使用容器,你能不能写...

list = objects;                               // if they're the same type
list.assign(objects.begin(), objects.end());  // if not
于 2010-03-29T14:27:41.630 回答
1

正如已经说过的,在使用它的同一表达式中对变量进行后递增会产生未定义的行为。但是,如果您希望保持紧凑的形式,您可以引入一个序列点并使用

for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i), i++);
于 2010-03-29T14:33:28.590 回答