Может ли std :: string перегрузить "substr" для rvalue * this и украсть ресурсы? - PullRequest
21 голосов
/ 17 февраля 2011

Мне пришло в голову, что я заметил, что операция std::string substr может быть намного более эффективной для значений, когда она может украсть выделенную память из *this.

Стандартная библиотека N3225 содержит следующее объявление функции-члена std::string

basic_string substr(size_type pos = 0, size_type n = npos) const;

Может ли реализация, которая может реализовать оптимизированную substr для перегрузки значений, предоставить две версии,один из которых мог бы повторно использовать буфер для строк rvalue?

basic_string substr(size_type pos = 0) &&;
basic_string substr(size_type pos, size_type n) const;

Я полагаю, что версия rvalue могла бы быть реализована следующим образом, повторно используя память *this установки *this в состояние перемещения.

basic_string substr(size_type pos = 0) && {
  basic_string __r;
  __r.__internal_share_buf(pos, __start + pos, __size - pos);
  __start = 0; // or whatever the 'empty' state is
  return __r;
}

Работает ли это эффективно в распространенных реализациях строк или это заняло бы слишком много домашнего хозяйства?

Ответы [ 3 ]

4 голосов
/ 17 февраля 2011

Во-первых, реализация не может добавить перегрузку, которая крадет источник, так как это было бы обнаружено:

std::string s="some random string";
std::string s2=std::move(s).substr(5,5);
assert(s=="some random string"); 
assert(s2=="rando");

Первое утверждение не будет выполнено, если реализация украла данные из s, а формулировка C ++ 0x фактически запрещает копирование при записи.

Во-вторых, это не обязательно будет оптимизация в любом случае: вам нужно будет добавить дополнительную служебную информацию в std::string, чтобы обработать случай, когда это подстрока большей строки, и это будет означать сохранение больших блоков вокруг, когда больше не было никаких строк, ссылающихся на большую строку, только некоторая ее подстрока.

0 голосов
/ 17 февраля 2011

Да, и, возможно, это должно быть предложено комитету по стандартам или может быть реализовано в библиотеке. Я действительно не знаю, насколько ценной была бы оптимизация. И это было бы интересное исследование само по себе.

Когда в gcc растет поддержка значения r this, кто-то должен попробовать его и сообщить, насколько он полезен.

0 голосов
/ 17 февраля 2011

Существует несколько строковых классов, реализующих копирование при записи.Но я бы не рекомендовал добавлять еще один строковый тип в ваш проект, если это не оправдано.

Просмотрите обсуждение в Строки C ++ с эффективным использованием памяти (интернирование, веревки, копирование при записи и т. Д.)

...