为什么C++正则表达式相关函数要使用输出参数而非按值返回结果?
关于regex_match输出参数设计的解答
这个设计并没有违反C++核心准则:核心准则中「输出参数属于代码坏味道」是通用场景下的最佳实践建议,而非不允许任何例外的强制规则。regex_match选择输出参数的形式,有明确的工程层面的合理性,主要原因可以分为三类:
- 性能复用的需求
std::match_results会存储完整的匹配分组、子串位置等信息,匹配内容复杂时内部会涉及堆内存分配。如果按值返回,每次调用都需要重新构造对象、分配对应内存。而使用输出参数的形式,用户可以在循环匹配等高频调用场景下复用同一个match_results实例,只需要每次调用前清空原有内容即可,能大幅减少不必要的内存分配、对象构造析构开销。
另外匹配失败的场景下,按值返回仍然需要构造一个空的match_results对象,而输出参数+bool返回值的设计下,匹配失败时不会对输出参数做无意义的修改,完全规避了额外开销。 - 历史版本的设计限制
正则库是C11版本正式加入标准库的,当时C标准中还没有std::optional类型,无法优雅地同时承载「匹配是否成功」和「匹配结果」两个信息。如果放弃输出参数,只能选择返回std::pair<bool, std::match_results<...>>,这种写法使用起来非常繁琐,而且对只需要判断匹配是否成功、不需要获取匹配详情的场景也会产生不必要的性能开销,反而不如输出参数的设计灵活。 - 自定义分配器的支持
std::match_results支持用户传入自定义分配器管理内部内存,使用输出参数的形式,用户可以提前构造好携带自定义分配器的match_results对象传入函数。如果改为按值返回,需要额外在函数参数中增加分配器指定的相关接口,会大幅提高接口的复杂度,也不符合STL算法的通用设计习惯。
补充说明:标准库也提供了不带输出参数的regex_match重载,不需要获取匹配结果的场景下可以直接调用仅返回bool的版本,本身就兼顾了不同场景的使用需求。
内容的提问来源于stack exchange,提问作者KHALED ISMAEEL
相关产品推荐
相关产品推荐

