6

std::stringa に部分文字列が含まれているかどうかを確認する関数があります。std::string_viewコピーが行われないように、文字列を として渡します。

bool containsSubstr(std::string_view str, std::string_view substr)
{
    return str.find(substr) != std::string::npos;
}

新しい C++17 フォールド式を使用して、文字列に複数の部分文字列が含まれているかどうかを確認する関数を作成したいと考えています。繰り返しますが、s で渡したいと思いstd::string_viewます。

どうやってやるの?

template<typename... Substrs>
bool containsAllSubstr(std::string_view str, Substrs... substrs)
{
    return  (containsSubstr(str, substrs) && ...);
}

私が知る限り、上記のバージョンは、部分文字列をそれらが入ったタイプとして受け取ります。したがって、 astd::stringがコピーされます。タイプを に修正するにはどうすればよいstd::string_viewですか? 何かのようなもの:

template<> // does not compile
bool containsAllSubstr(std::string_view str, std::string_view... substrs)
{
    return  (containsSubstr(str, substrs) && ...);
}
4

1 に答える 1

10

特定の型の関数パラメーター パックを持つことはできません。しかし、これは問題ありません(追加したら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);
于 2018-03-19T13:08:28.740 に答える