鉴于
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);
}
答案 0 :(得分:11)
前者是未定义的行为。在函数调用list[i]
之前或之后,未指定是否评估objects.at
(为赋值的lhs提供左值)。
因此,表达式的各个部分都有一个合法的排序,其中i
被访问(在list[i]
中)并被单独修改(在i++
中),没有插入序列点。
这正是C ++标准中未定义行为的条件 - 是否存在这样的合法排序。 IIRC的C标准表达方式略有不同,但效果相同。
如果有疑问,请不要编写使用增量运算符的表达式,并在表达式的其他位置使用相同的值。您可以使用逗号运算符(i++, i++
很好)和条件运算符(i ? i++ : i--
很好),因为它们中有序列点,但它很少值得。同样地||
和&&
,p != end_p && *(p++) = something;
之类的东西并非完全不可信。任何其他用途,如果你盯着它足够长的时间,你通常可以制定一个评估令,这会使事情变得混乱。
除了复杂的for
表达式和for
循环与空体的可理解性之外。
答案 1 :(得分:6)
如果有疑问,请选择更容易理解的形式(扩展循环)。
(我认为list[i] = objects.at(i++)
导致未定义的行为。)
答案 2 :(得分:1)
在与i
相同的表达式中引用i++
可能是未定义的行为。但既然看起来你正在使用容器,你可以写一下......
list = objects; // if they're the same type
list.assign(objects.begin(), objects.end()); // if not
答案 3 :(得分:1)
正如已经说过的那样,在使用的同一表达式中对变量进行后递增会产生未定义的行为。 但是,如果您希望保留紧凑形式,可以引入序列点并转到
for(unsigned int i = 0; i < objects.size(); list[i] = objects.at(i), i++);