Если у меня есть std::string
:
std::string s{"hello"};
и al oop, который изменяет его на месте, например так:
for (auto &c: s)
c = std::toupper(c);
Я могу заменить его на эквивалент transform
:
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c) -> unsigned char
{ return std::toupper(c); });
, и эти фрагменты генерируют идентичную сборку . Они также имеют схожую производительность .
Однако, если у меня есть std::vector<std::string>
:
std::vector<std::string> v {"hello", "how", "are", "you"};
и я модифицирую его на месте следующим образом:
for (auto & s : v)
for (auto &c: s)
c = std::toupper(c);
эквивалентное преобразование должно быть:
std::transform(std::begin(v), std::end(v), std::begin(v),
[](auto s) {
std::transform(std::begin(s), std::end(s), std::begin(s),
[](unsigned char c) -> unsigned char { return std::toupper(c); });
return s;
});
Однако версия transform
генерирует вдвое больше сборка , а выполняет соответственно плохо , что меня удивляет.
Разве std::transform
не является в этом случае абстракцией с нулевой стоимостью или я просто неправильно ее использую?