Глядя на куске кода, как это (добавлены комментарии):C++ конкатенация строки Оптимизация
std::string some_var;
std::string some_func(); // both are defined, but definition is irrelevant
...
return "some text " + some_var + "c" + some_func(); // intentionally "c" not 'c'
Мне было интересно, , в каких случаях operator +
из std::string
должен сделать копию (в смысле использования копии -конструкция/назначение, а не копирование внутреннего буфера, например, если применяется SSO), и что фактически копируется. Быстрый взгляд на cppreference был лишь частично полезным, так как он перечисляет 12 (!) Разных случаев. В частности, я прошу, чтобы подтвердить свое понимание страницы:
- Case 1) делает копию LHS затем копирует РИТ до конца этой копии
- В C++ 98 Случай 2) - 5) временная строка построена из аргумента
char/const char*
, что затем приводит к случаю 1) - В C++ 11 Случай 2) - 5) временная строка построена из аргумента
char/const char*
, что затем приводит к случаю 6) или 7) - В C++ 11 Случай 6) - 12) аргумент r-value будет мутирован с
insert/append
и, если achar/const char*
аргумент было предоставлено не временное место из-за перегрузок наinsert/append
. Во всех случаях возвращается значение r для облегчения дальнейшей цепочки. Копии не копируются (кроме копии аргументов, которые должны быть добавлены/вставлены в месте вставки). Может потребоваться перемещение содержимого строки.
Цепочка, подобная приведенному выше примеру, должна приводить к: 2) -> 6) -> 11) -> 8), без каких-либо копий каких-либо lhs, а просто модификации буфера r -значение, полученное в результате первой операции (создание временной строки).
Поэтому это кажется столь же эффективным, как и operator +=
, как только operator +
использует по крайней мере аргумент r-value. Это правильно, и есть ли смысл использовать operator +=
по сравнению с operator +
в C++ 11 и после этого, если оба аргумента не являются строками l-value?
Какие оптимизации может сделать компилятор дополнительно?
Изменить: уточнить цель вопроса. Исходная часть касается специфики только языка (выполнение непогашения); последний вопрос касается дополнительных оптимизаций.
Исправлено, что я считаю опечаткой. Откат назад, если вы имели в виду 'some_fun()'. – Bathsheba
на самом деле не была опечаткой, но я предполагаю, что ваша версия более понятна в контексте C++. – midor
Поучительно компилировать с помощью 'g ++ -save-temps' и смотреть на результат сборки ассемблера на разных уровнях оптимизации. С '-O3' он вызывает' string :: reserve() 'once и' string :: append() 'четыре раза для вашей части кода. –