Код: Выделить всё
char*Параметр строки сменной строки должен оцениваться только один раз (по крайней мере, в случае, если это функтор). < /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 Код: Выделить всё
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;
}
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Подробнее здесь: https://stackoverflow.com/questions/797 ... ng-possibl
Мобильная версия