You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何针对特定类型使用C++17折叠表达式?实现多子串检测函数

用C++17折叠表达式实现多子串全包含检测

嘿,这个需求用C++17的折叠表达式来实现超顺手!咱们基于你现有的containsSubstr函数(或者直接内嵌逻辑),就能轻松写出支持任意多个子串检测的模板函数。

实现方案一:复用现有containsSubstr函数

既然你已经有了单条检测的函数,直接用它结合折叠表达式就好,代码非常简洁:

#include <string_view>

// 你原有的单子串检测函数
bool containsSubstr(std::string_view str, std::string_view substr) {
    return str.find(substr) != std::string::npos;
}

// 多子串全包含检测函数
template <typename... Substrs>
bool containsAll(std::string_view str, Substrs&&... substrs) {
    // 逻辑与折叠表达式:所有子串检测都通过才返回true
    return (containsSubstr(str, std::string_view(std::forward<Substrs>(substrs))) && ...);
}

实现方案二:直接内嵌find逻辑(无需依赖原有函数)

如果不想依赖单独的containsSubstr,也可以把检测逻辑直接写在折叠表达式里:

#include <string_view>

template <typename... Substrs>
bool containsAll(std::string_view str, Substrs&&... substrs) {
    return ((str.find(std::string_view(std::forward<Substrs>(substrs))) != std::string::npos) && ...);
}

关键细节解释

  • 折叠表达式的作用:(expr && ...)是C++17新增的逻辑与折叠,它会自动遍历参数包substrs,对每个子串执行expr,然后将所有结果做逻辑与运算。只要有一个子串不存在,整个表达式就会返回false,完全符合“包含所有子串”的需求。
  • 避免拷贝的技巧:std::string_view(std::forward<Substrs>(substrs))这一步很重要——它能把任何可转换为std::string_view的类型(比如const char*、std::string、std::string_view本身)都转换成视图,全程不会产生字符串拷贝,完美延续了你原函数的性能优势。
  • 完美转发:用std::forward是为了保留参数的原始值类别(左值/右值),确保转换std::string_view时的效率最优。

使用示例

#include <iostream>
#include <string>

int main() {
    const std::string testStr = "C++17 Fold Expressions are awesome!";
    
    // 检测多个子串是否都存在
    bool hasAll = containsAll(testStr, "C++17", "Fold", "awesome");
    std::cout << std::boolalpha << hasAll << std::endl; // 输出true
    
    // 缺少一个子串的情况
    bool missing = containsAll(testStr, "C++17", "Java");
    std::cout << missing << std::endl; // 输出false
    
    // 支持直接传入const char*或std::string_view
    std::string_view sub1 = "Expressions";
    bool hasSubs = containsAll(testStr, sub1, "are");
    std::cout << hasSubs << std::endl; // 输出true
    
    return 0;
}

注意事项

  • 编译器要求:必须使用支持C17的编译器(比如GCC 7+、Clang 6+、MSVC 2017+),编译时记得开启C17标准(例如-std=c++17)。
  • 空字符串处理:根据std::string::find的行为,空字符串会被认为是任何字符串的子串,所以如果参数包里传入空串,函数会直接判定为包含。
  • 大小写敏感:这个实现是区分大小写的,如果需要忽略大小写的检测,需要额外添加字符转换逻辑(比如统一转成小写后再检测)。

内容的提问来源于stack exchange,提问作者dani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:18:14