Может ли std::string перегрузить "substr" для rvalue * this и украсть ресурсы?
Мне пришло в голову, что я заметил, что операция std::string
substr
может быть намного более эффективной для rvalues, когда она может украсть выделенную память из *this
.
Стандартная библиотека N3225 содержит следующее объявление функции функции std::string
basic_string substr(size_type pos = 0, size_type n = npos) const;
Может ли реализация, которая могла бы реализовать оптимизированную перегрузку substr
для rvalues, и предоставить две версии, одна из которых могла бы повторно использовать буфер для строк 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;
}
Эффективно ли это работает на общих строковых реализациях или это потребует слишком много домашнего хозяйства?
Ответы
Ответ 1
Во-первых, реализация не может добавить перегрузку, которая крадет источник, поскольку это можно было бы обнаружить:
std::string s="some random string";
std::string s2=std::move(s).substr(5,5);
assert(s=="some random string");
assert(s2=="rando");
Первое утверждение потерпит неудачу, если реализация украдет данные из s
, а формулировка С++ 0x по существу запрещает копирование при записи.
Во-вторых, в любом случае это не обязательно будет оптимизацией: вам нужно добавить дополнительное обслуживание в std::string
, чтобы обработать случай, когда это подстрока большей строки, и это будет означать сохранение больших блоков вокруг, когда больше не было строк, ссылающихся на большую строку, просто на какую-то подстроку.
Ответ 2
Да, и, возможно, это должно быть предложено комитету по стандартизации или, возможно, реализовано в библиотеке. Я не знаю, насколько ценна оптимизация. И это было бы интересным исследованием самостоятельно.
Когда gcc увеличивает поддержку r-value this
, кто-то должен попробовать и сообщить, насколько он полезен.
Ответ 3
Существует несколько классов строк, реализующих copy-on-write. Но я бы не рекомендовал добавлять еще один тип строки в ваш проект, если это действительно не оправдано.
Ознакомьтесь с обсуждением в Строках С++ с эффективной памятью (интернирование, веревки, копирование и запись и т.д.)