如何使用特定类型的折叠表达式?
Howto use a fold expression with a specific type?
我有一个函数可以检查 std::string
是否包含子字符串。我将字符串作为 std::string_view
传递,这样就不会发生复制。
bool containsSubstr(std::string_view str, std::string_view substr)
{
return str.find(substr) != std::string::npos;
}
我现在想创建一个函数,使用新的 C++17 折叠表达式来检查一个字符串是否包含多个子字符串。同样,我想通过 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) && ...);
}
您不能拥有特定类型的函数参数包。但这很好(一旦你添加 const&
):
template <typename... Substrs>
bool containsAllSubstr(std::string_view str, Substrs const&... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
不会制作任何副本,如果您传入无法转换为 string_view
的内容,则不会编译。如果你想做到SFINAE-friendly,可以只添加一个条件:
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]);
但是你实际上并没有立即拥有一包。但是,你可以只写一个循环。或者,如果您根本不需要 compile-time 尺寸:
bool containsAllSubstr(std::string_view str, std::initializer_list<std::string_view> substrs);
我有一个函数可以检查 std::string
是否包含子字符串。我将字符串作为 std::string_view
传递,这样就不会发生复制。
bool containsSubstr(std::string_view str, std::string_view substr)
{
return str.find(substr) != std::string::npos;
}
我现在想创建一个函数,使用新的 C++17 折叠表达式来检查一个字符串是否包含多个子字符串。同样,我想通过 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) && ...);
}
您不能拥有特定类型的函数参数包。但这很好(一旦你添加 const&
):
template <typename... Substrs>
bool containsAllSubstr(std::string_view str, Substrs const&... substrs)
{
return (containsSubstr(str, substrs) && ...);
}
不会制作任何副本,如果您传入无法转换为 string_view
的内容,则不会编译。如果你想做到SFINAE-friendly,可以只添加一个条件:
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]);
但是你实际上并没有立即拥有一包。但是,你可以只写一个循环。或者,如果您根本不需要 compile-time 尺寸:
bool containsAllSubstr(std::string_view str, std::initializer_list<std::string_view> substrs);