使用std::variant不依赖多态调用同名方法,解决模板推导失败问题
解决方案
要实现f函数正确调用对应实例的foo方法,直接使用标准库提供的std::visit工具访问std::variant存储的实例即可,无需手动判断类型,也不需要多态支持。
最简实现(C++17及以上支持)
直接传入泛型lambda给std::visit,会自动匹配当前variant持有的类型执行对应逻辑:
void f(const Object& ob) { std::visit([](const auto& instance) { instance.foo(); }, ob); }
实现说明
std::visit会自动识别Object当前存储的具体类型(A/B/C中的一种)- 泛型lambda会为每一种可能的类型生成对应的调用逻辑,确保调用到对应类型定义的
foo方法 - 代码无冗余,后续新增支持的类型时只要该类型定义了
foo方法,不需要修改f函数的实现
兼容C++14的实现方式
如果使用C++14标准,不支持泛型lambda作为访问者,可以自定义访问者结构体:
struct FooVisitor { void operator()(const A& a) const { a.foo(); } void operator()(const B& b) const { b.foo(); } void operator()(const C& c) const { c.foo(); } }; void f(const Object& ob) { std::visit(FooVisitor{}, ob); }
实现说明
- 自定义的访问者结构体需要对
std::variant定义的所有可选类型都重载()运算符 std::visit会自动匹配当前持有的类型,调用对应的重载方法
修改后完整代码运行会输出C,和传入getClass(2)的预期结果一致。
内容的提问来源于stack exchange,提问作者Ionut Alexandru
相关产品推荐
相关产品推荐

