Как использовать выражение сгиба с определенным типом?
У меня есть функция, чтобы проверить, если std::string
содержит подстроку Я передаю струны как std::string_view
, так что копия не имеет места.
bool containsSubstr(std::string_view str, std::string_view substr)
{
return str.find(substr) != std::string::npos;
}
Теперь я хочу создать функцию, используя новые 17-кратные выражения C++, чтобы проверить, содержит ли строка несколько подстрок. Опять хочу пройти мимо std::string_view
s.
Как я могу это сделать?
template<typename... Substrs>
bool containsAllSubstr(std::string_view str, Substrs... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
Насколько я знаю, вышеприведенная версия будет принимать подстроку как тип, с которым они пришли. std::string
будет скопирован. Как я могу исправить тип std::string_view
? Что-то вроде:
template<> // does not compile
bool containsAllSubstr(std::string_view str, std::string_view... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
1 ответ
Вы не можете иметь пакет параметров функции определенного типа. Но это нормально (как только вы добавите const&
):
template <typename... Substrs>
bool containsAllSubstr(std::string_view str, Substrs const&... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
Это не сделает никаких копий и просто не скомпилируется, если вы передадите что-то не конвертируемое в string_view
, Если вы хотите сделать его SFINAE-дружественным, просто добавьте условие:
template <typename... Substrs,
std::enable_if_t<(std::is_convertible_v<Substrs const&, std::string_view> && ...), int> = 0>
bool containsAllSubstr(std::string_view str, Substrs const&... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
Или, если вы открыты для небольшого изменения синтаксиса, вы можете взять массив:
template <size_t N>
bool containsAllSubstr(std::string_view str, std::string_view (&substrs)[N]);
но тогда у вас на самом деле нет пакета сразу. Но тогда вы можете просто написать цикл. Или, если вам вообще не нужен размер времени компиляции:
bool containsAllSubstr(std::string_view str, std::initializer_list<std::string_view> substrs);