Функция замены строки, которая заменяет все входы на новую строку, возможно, от фанктора, в качестве шаблона для всех стC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Функция замены строки, которая заменяет все входы на новую строку, возможно, от фанктора, в качестве шаблона для всех ст

Сообщение Anonymous »

Я ищу (своего рода универсальный швейцарский армейский нож), которая заменяет все вхождения строки поиска в данном строке., std :: string_view , std :: string , char*(*) () , std :: function , ...). Все, что оценивает новую строку, также должно работать в качестве аргумента для нового текста замены. /> < /li>
Параметр строки сменной строки должен оцениваться только один раз (по крайней мере, в случае, если это функтор). < /p>
< /li>
Функция должна быть оптимизирована также для случая, когда не происходит замены. То есть он не должен создавать дорогие временные объекты (например, временную строку), если они впоследствии не используются. (Причина: мой вариант использования состоит из очень большого количества вызовов в функцию замены только с несколькими фактическими заменами.) (Поэтому я не добавляю тег VS2022.)

Код: Выделить всё

using String = std::wstring;

template 
requires std::is_assignable_v ||
std::is_assignable_v
String& replace_all(String& string, std::xstring_view _search, Replace replaceExpr)
{
using string_view = std::basic_string_view;
string_view search(_search);
if(!search.empty())
{
String replaceStr; bool replaceStrSet = false;
for(size_t pos = 0; (pos = string.find(search, pos)) != String::npos; pos += replaceStr.size())
{
if(!replaceStrSet)
{
if constexpr(std::is_invocable_r::value)
replaceStrSet = true, replaceStr = std::invoke(replaceExpr);
else
replaceStrSet = true, replaceStr = replaceExpr;
}
string.replace(pos, search.size(), replaceStr);
}
}
return string;
}
< /code>
Проблемы: это не шаблон типа строки. И в нем хранится копия строки замены в Replacestr 
. Это ненужнее и нежелательное, если std :: invoke (replyexpr) дает string_view . Но с другой стороны, если он будет просто хранить константу*, то Replacestr.size () не будет работать. Так что, может быть, лучше всегда сохранять результат invoke в string_view ? ссылка. Этого также следует избегать с помощью дизайна этой функции. Я попытался упростить и придумал: < /p>

Код: Выделить всё

template 
using char_type_t = typename std::conditional_t<
std::is_same_v,
char,
typename std::conditional_t
>;

auto& replace_all1(auto& string, auto search, auto replace)
{
using string_type = decltype(string);
using char_type = char_type_t;
using string_view = std::basic_string_view>;
size_t pos = string.find(search);
if(pos == std::basic_string::npos)
return string;
string_view search_{search};
auto do_replace = [&](string_view replaceStr)
{
do
{
string.replace(pos, search_.size(), replaceStr);
pos += std::size(replaceStr);
} while((pos = string.find(search, pos)) != std::basic_string::npos);
};
if constexpr(std::is_invocable_v)
{
const auto& replace_ret = replace();
do_replace(replace_ret);
}
else
do_replace(replace);
return string;
}
edit:
i отредактировал вторую функцию (replace_all1), используйте std :: string_view для текста для поиска и для того, чтобы текст, чтобы заменить, как предложил Pepijn kramer, внедренное IGOR TANDETNIK, чтобы переместить код, что я в курсе, так что я могу оставить код, так что я в курсе, так что в «Код», так что в том, что я смотрю в код, так что я могу оставить код, так что в «Поведенном коде», так что в «Поведенном коде», так что в том, что я могу сохранить код, так что я могу составить код, так что в «Поведенном коде». Ссылка на LVALUE, чтобы расширить свое срок службы, например, SO: const auto & replace_ret = replace ();
Это, кажется, работает со всеми типами, которые мне требуются для параметра замены. То есть для нового текста я могу использовать char*, std :: string_view , std :: string , char*(*) () и std :: function (или wchar_t equivalents, как я в Windows). Но ...
Текущий вопрос:
Теперь у меня есть вторая шаблонная вспомогательная функция char_type_t , чтобы получить базовый тип символа параметра замены, чтобы я мог построить std :: string_view с правильным типом. Но я действительно хочу функцию «все в одном», если это возможно.

Код: Выделить всё

char_type_t
и replace_all1 ) быть объединены или все равно преобразовано в один? Спасибо

Подробнее здесь: https://stackoverflow.com/questions/797 ... ng-possibl
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»