Стандарт C ++ ничего не гарантирует по этому поводу.Однако почти любой современный компилятор на обычном оборудовании должен преобразовывать оба цикла в один и тот же код (при условии, что оптимизация включена), потому что семантика копирования символа или обращения к ссылке на него не имеет значения на уровне машинного кода.
Вот три основных компилятора, которые делают именно это: https://godbolt.org/g/XfRX38
volatile char x;
void fooCopy(std::string str)
{
for (char c : str) {
x = c;
}
}
void fooReference(std::string str)
{
for (char& c : str) {
x = c;
}
}
clang
разворачивает цикл с коэффициентом 8, gcc
делает его простым, а MSVC
имеет точно такой жетело цикла в виде gcc
, но с гораздо большим количеством границ / проверок стека вокруг него.
Но если вы сосредоточитесь на теле цикла, машинный код будет абсолютно идентичен для двух функций (без учета метки и имен регистров)) для каждого компилятора.
Лично я не использую ссылки на const для встроенных числовых типов, потому что я знаю (в моем случае для работы на x86), что CPU все равно будет хранить их в регистре и чтоих копирование не имеет накладных расходов.Это не должно быть правдой на каждом оборудовании, но в этом случае вам нужно исследовать себя - скорее всего, ваш компилятор знает это лучше, чем вы.