设计函数API避免对象生命周期问题:阻止临时vector传入make_scanner
解决方案:禁止
make_scanner接受临时vector对象 核心思路
通过添加被删除的右值引用重载,让编译器在传入临时vector(右值)时直接触发编译错误,同时完全保留具名左值vector的正常调用逻辑。
修改后的完整代码
// 原左值引用版本:仅接受具名vector auto make_scanner(std::vector<int> const &v) { auto begin = v.cbegin(); auto end = v.cend(); return [begin, end] () mutable -> int { return (begin != end) ? *begin++ : 0; }; } // 删除右值引用版本:明确禁止传入临时vector auto make_scanner(std::vector<int>&&) = delete;
原理说明
- 当传入具名左值vector时,编译器会匹配
const std::vector<int>&版本,代码正常编译运行,完全保留原有逻辑。 - 当传入临时右值vector(比如
std::vector<int>{1,2,3})时,编译器会优先匹配更贴合的std::vector<int>&&重载——而该函数被标记为delete,直接触发编译错误,从根源避免了悬空迭代器的问题。
测试验证
- 正常用法(左值):编译通过,运行逻辑不受影响
std::vector<int> data = {1, 2, 3}; auto scanner = make_scanner(data); for (int x = scanner(); x != 0; x = scanner()) { // 业务逻辑代码 }
- 错误用法(临时对象):编译器直接报错(例如GCC会提示
use of deleted function 'auto make_scanner(std::vector<int>&&)'),符合预期
// 编译失败,禁止此类调用 auto scanner = make_scanner(std::vector<int>{1, 2, 3});
内容的提问来源于stack exchange,提问作者Adrian McCarthy
相关产品推荐
相关产品推荐

