Warning C26817

Potentially expensive copy of variable name in range-for loop. Consider making it a const reference (es.71).

For more information, see ES.71 notes in the C++ Core Guidelines.

Example

If a range-for loop variable isn't explicitly marked as a reference, it gets a copy of each element iterated over:

#include <vector>

class MyComplexType {
    int native_array[1000];
    // ...
};

void expensive_function(std::vector<MyComplexType>& complex_vector_ref)
{
    for (auto item: complex_vector_ref) // Warning: C26817
    {
        // At each iteration, item gets a copy of the next element
        // ...
    }
    for (MyComplexType item: complex_vector_ref)
    {
        // It happens whether you use the auto keyword or the type name
        // ...
    }
}

The warning is ignoring some types that are cheap to copy like for scalars (pointers, arithmetic types, and so on).

To fix this issue, if the loop variable isn't mutated anywhere in the loop, make it a const reference:

#include <vector>

class MyComplexType {
    int native_array[1000];
    // ...
};

void less_expensive_function(std::vector<MyComplexType>& complex_vector_ref)
{
    for (const auto& item: complex_vector_ref)
    {
        // item no longer gets a copy of each iterated element
        // ...
    }
    for (const MyComplexType& item: complex_vector_ref)
    {
        // item no longer gets a copy of each iterated element
        // ...
    }
}

The const keyword makes the loop variable immutable. Use of a non-const reference makes it possible to inadvertently use the reference to modify the container's elements. If you need to modify only the local loop variable, the potentially expensive copying is unavoidable.