不使用继承,解决遗留API多类型变量调用functionB的低侵入式改法
问题描述
原有代码示例:
functionA () { TypeA o = TypeA{"abcd"}; functionB(o); }
假设已修改functionB使其支持新类型TypeB,想要实现类似以下逻辑:
functionA () { if (useA) { TypeA o = TypeA{"abcd"}; } else { TypeB o = TypeB{"abcd"}; } functionB(o); }
但由于变量o未在if-else结构外声明,会报未定义错误。请问最低侵入式的代码修改方案是什么?
补充说明:
if (useA) functionB(TypeA{...}); else functionB(TypeB{...});
functionB位于一个大型try代码块中,无法重复编写两次调用逻辑。
解决方案
方案一:立即执行lambda表达式(最低侵入性)
直接用立即执行的lambda包裹对象创建与functionB调用逻辑,既不用重复编写functionB的调用代码,也解决了变量作用域问题,改动量极小:
functionA () { [&]() { if (useA) { TypeA o = TypeA{"abcd"}; functionB(o); } else { TypeB o = TypeB{"abcd"}; functionB(o); } }(); }
方案二:C++17+ std::variant + std::visit
如果编译器支持C17及以上,可采用现代C的变体类型实现,逻辑更清晰:
#include <variant> functionA () { std::variant<TypeA, TypeB> o = useA ? std::variant<TypeA, TypeB>(TypeA{"abcd"}) : TypeB{"abcd"}; std::visit([&](auto&& obj) { functionB(obj); }, o); }
两种方案中,lambda方案无需引入额外头文件,对原有代码的改动最少,完全符合“最低侵入式”的要求。
内容的提问来源于stack exchange,提问作者LunaticJape
相关产品推荐
相关产品推荐

