寻求支持惰性求值与多类型兼容的通用全字符串替换模板函数实现
寻求支持惰性求值与多类型兼容的通用全字符串替换模板函数实现
我需要实现一个高度通用的全字符串替换模板函数,和常规的替换函数比有不少特殊的设计要求,希望能得到大家的帮助。下面是详细的需求和设计思路:
核心设计要求
- 多类型兼容的字符串操作:能处理
std::string、std::wstring等所有std::basic_string风格的类,甚至其他提供必要接口的自定义字符串类;搜索串也可以是任意类字符串类型(char*、std::string_view等)。 - 惰性求值的替换文本:替换文本支持两种形式——直接的类字符串值(比如
char*、std::string、std::string_view),或惰性求值的可调用对象(比如char*(*)()、std::function<std::string()>这类函数/函数对象)。只有当原字符串中找到搜索串时,才会触发替换文本的求值。 - 替换文本仅求值一次:哪怕搜索串在原字符串中出现多次,替换文本(尤其是functor类型的)也只会被计算一次,避免重复执行带来的开销。
- 替换文本类型灵活:替换文本的类型可以和原字符串、搜索串完全不同,只要最终能转换为与原字符串兼容的
std::basic_string_view<>即可。比如返回临时std::string的函数也能正常工作,且要尽可能延长临时对象的生命周期,避免不必要的拷贝。 - 无匹配时的性能优化:当原字符串中没有找到搜索串时,绝对不能创建昂贵的临时对象(比如临时
std::string)——我的使用场景里,大部分调用都不会触发替换,所以这部分性能优化非常关键。 - 极致通用的参数设计:替换文本参数要接受所有能生成对应
std::basic_string_view<>的类型,不管是直接值还是可调用对象,只要最终结果能赋值给对应类型的basic_string_view就行。
期望的函数原型
我希望函数的原型尽可能简洁通用,大概是这样:
auto& replace_all(auto& string, auto search, auto replace)
测试用例
下面是我用来验证函数的测试代码,最终断言应该能通过:
#include <string> #include <functional> #include <cassert> int main() { std::string t = "hello world"; replace_all(t, "hello", []() { return "Hello"; }); replace_all(t, std::string("Hello"), "HELLO"); replace_all(t, "world", std::string("World")); replace_all(t, "World", []() { return std::string("WORLD"); }); replace_all(t, "WORLD", []() { return "sunshine"; }); replace_all(t, std::string("HELLO"), []() { return "good day"; }); replace_all(t, "&", []() -> std::string { return (const char*)0; }); // 这个functor永远不会被求值! assert(t == "good day sunshine"); }
现状说明
我自己尝试写了一个初步版本,但还没法完全满足所有要求,也参考了一些改进建议,不过还是希望能得到一个更完善的单函数实现。优先支持VS2022 + C20环境,当然能兼容其他编译器或更高C标准的实现也能帮助到其他有类似需求的人。
内容来源于stack exchange
相关产品推荐
相关产品推荐

