Is clang always right in warning me to preventing copying?

257 Views Asked by At

Consider the following code:

std::vector<std::pair<char, char>> v;

for (const auto &p : v) {
   // ...
}
for (const auto &[first, second] : v) {
   // ...
}

There is a vector of pairs of chars and two ways to iterate over the elements using range for loop. In the first case p becomes a reference to a pair while in the second case (if not optimized) first and second become references to the elements of the pair. But the pair of chars is just 2 bytes long while even a single reference is larger. So, I assume that the following code should be more efficient (again, not considering optimization):

std::vector<std::pair<char, char>> v;

for (const auto p : v) {
   // ...
}
for (const auto [first, second] : v) {
   // ...
}

It should be more efficient to copy 2 bytes to local variables and use them at known offsets rather than to create a reference and access the elements of the pair dereferencing it. But clang produces warnings (that are taken as errors in my system):

loop variable 'p' creates a copy from type 'const std::pair<char, char>'
use reference type to prevent copying
loop variable '<structured bindings>' creates a copy from type 'const std::pair<char, char>'
use reference type to prevent copying

The same warning is produced if I use std::list instead of std::vector.

Is that always true that iterating pairs by reference is more efficient than by value (and why if that is true). If not, is that a bug in clang that it is over restrictive?

0

There are 0 best solutions below