Как использовать выражение сгиба с определенным типом?

У меня есть функция, чтобы проверить, если 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_views.

Как я могу это сделать?

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);
Другие вопросы по тегам