Difference Between For Each and Index-based Loop

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
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.


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
Topic archived. No new replies allowed.