Difference Between For Each and Index-based Loop

Jul 25, 2015 at 3:58am
I have two pieces of code that I was expecting to work the same and I can't figure out why they don't.

First, this is the way that works how I expected:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
size_t i = 0;
for (auto element : elements)
{
	auto it = existing_elements.find(element);

	if (it == existing_elements.end())
	{
		existing_elements.insert(std::make_pair(element, i));

		indices.push_back(i);
		sorted_vertices.push_back(vertex_positions[element[0] - 1]);
		sorted_uvs.push_back(vertex_uvs[element[1] - 1]);
		sorted_normals.push_back(vertex_normals[element[2] - 1]);

		++i;
	}
	else
	{
		indices.push_back((*it).second);
	}
}


And here is the similar code that does not work and gets stuck on the else clause in an infinite loop:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
for (size_t i = 0; i < elements.size(); )
{
	auto element = elements[i];
	auto it = existing_elements.find(element);

	if (it == existing_elements.end())
	{
		existing_elements.insert(std::make_pair(element, i));

		indices.push_back(i);
		sorted_vertices.push_back(vertex_positions[element[0] - 1]);
		sorted_uvs.push_back(vertex_uvs[element[1] - 1]);
		sorted_normals.push_back(vertex_normals[element[2] - 1]);

		++i;
	}
	else
	{
		indices.push_back((*it).second);
	}
}
Last edited on Jul 25, 2015 at 6:24am
Jul 25, 2015 at 5:03am
The two loops are not equivalent.

In the first, iterating through the elements in the container is managed by the compiler. In the second, you use i, however i is not sufficient for this purpose.

An equivalent loop might look more like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    for (std::size_t index = 0, i = 0; index < elements.size(); ++index)
    {
        auto it = existing_elements.find(elements[index]);

        if (it == existing_elements.end())
        {
            // do stuff using value of i here

            ++i;
        }
        else
        {
            // do stuff
        }
    }


Note that the use of index and i are not interchangeable.


Jul 25, 2015 at 7:01am
Thanks. I think I get it now. I was only increasing i on some of the loop iterations so it didn't work to use it as the looping variable.

Here is what I have now. It only increases the unique index after finding a unique element, but relies on the i variable to iterate through the entire container.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
	for (std::size_t i = 0, unique_index = 0; i < elements.size(); ++i)
	{
		const auto& element = elements[i];
		const auto it = unique_elements.find(element);

		if (it == unique_elements.end())
		{
			unique_elements.insert(std::make_pair(element, unique_index));

			indices.push_back(unique_index);
			sorted_vertices.push_back(vertex_positions[element[0] - 1]);
			sorted_uvs.push_back(vertex_uvs[element[1] - 1]);
			sorted_normals.push_back(vertex_normals[element[2] - 1]);

			++unique_index;
		}
		else
		{
			indices.push_back((*it).second);
		}
	}
Last edited on Jul 25, 2015 at 7:15am
Topic archived. No new replies allowed.