template <typename ty_char, /* template <typename> typename ... tys_str
↑ I cant define the parameter pack
to express that paramater pack is constrainted to basic_string classes with a template argument */ >
void
concat_strings( basic_string<ty_char> & _buffer,
tys_str<ty_char> const & ... _string )
{
static_assert( is_same<basic_string<ty_char>::size_type, size_t>::value );
size_t l_min_size = 0;
for( auto const & l_string : {_string...} )
{
l_min_size += l_string.size( );
}
_buffer.reserve( l_min_size );
for( auto const & l_string : {_string...} )
{
_buffer += _string;
}
}
Я пытался реализовать функцию, которая получает ссылку на буфер и объединяет другие постоянные строки. Я хочу, чтобы функция получала аргументы без выделения массива. Тем не менее, я чувствую, что функция становится более грязной и совершенно неправильной. Это правильный способ реализации функции?
Если вы хотите убедиться, что разрешены только строки, просто определите их как таковые:
template <typename ty_char, typename ... tys_str>
void concat_strings
(
std::basic_string<ty_char>& buffer,
std::basic_string<tys_str> const& ... strings
)
Тогда вместо циклов по массивам выражения fold — ваш друг:
buffer.reserve( ( strings.length() + ... ) );
// ^ ^
( (buffer += strings), ... );
Требуется C++17 для выражений свертки; код до С++ 17 полагался на рекурсию в переменных параметрах, чтобы избежать промежуточных массивов (которые в любом случае могут быть оптимизированы).
Вам не нужен static_assert
, кстати, стандарт гарантирует, что size_type
уже есть size_t
.
Вместо этого вы можете захотеть убедиться, что все строки имеют один и тот же тип, опять же с выражением fold:
static_assert( (std::is_same_v<ty_char, tys_str> && ...) );
Странно, что clang++ в сообществе Visual Studio 2022, Windows 10, показывает мне ошибки: «выражения сгиба не относятся к пакету параметров», но нет проблем с созданием исполняемой программы с функцией «concat_strings». Даже в командной строке clang++.exe не выдает ошибок. Я думаю, что это ошибка IDE.
Не слишком много опыта работы с MSVC, я избегаю его везде, где это возможно... Его преимуществом является его простая установка, признано - другие IDE, такие как eclipse или code::blocks, требуют определенных усилий для их правильной работы (необходимо включать внешний компилятор), но как только эта задача выполнена, они превосходят (опять же признал, что MS приложил немало усилий, чтобы сократить расстояние, но все же они остаются позади).
Перейдите к C++20:template <typename ty_char, std::same_as<ty_char> ... tys_str>
вместо static_assert
.
Прием
std::initializer_list<std::basic_string<ty_char>>
может быть более простой альтернативой.