前序文章请看:
C++模板元编程详细教程(之一)
C++模板元编程详细教程(之二)
C++模板元编程详细教程(之三)
C++模板元编程详细教程(之四)
C++模板元编程详细教程(之五)
C++模板元编程详细教程(之六)
C++模板元编程详细教程(之七)
C++模板元编程详细教程(之八)
C++模板元编程详细教程(之九)
C++模板元编程详细教程(之十)
访问函数
上一节我们介绍了如何编写一个「访问器」,以及用std::visit来实现访问。那么这一节就来手撸一个访问函数visit,用于使用访问器来访问variant。
前面我们介绍过如何写一个动态的get方法,这里的思路与它如出一辙,在静态编译期把variant的所有情况都生成一个对应的方法,这里我们就需要与访问器进行关联,调用对应的访问方法。等到运行时,根据当前variant的index值选择调用对应的访问函数。
我们这里只实现一个支持单个variant的情况,如果读者希望实现一个跟STL中相同的支持多个variant的情况可以尝试自行完成。话不多说,直接上代码:
// 辅助函数2
template <typename Visitor, typename R, typename Variant, size_t Index>
R visit_detail_invoke(Visitor &&vis, Variant &&var) {
return std::invoke(vis, std::get<Index>(var));
}
// 辅助函数1
template <typename Visitor, typename R, typename Variant, size_t... Index>
R visit_detail(Visitor &&vis, Variant &&var, const std::index_sequence<Index...> &) {
std::array<R(Visitor &&, void *), std::variant_size_v<Variant>> funcs {
// 按照变参展开,如果遇到类型相同的也会匹配同一个函数实例
&visit_detail_invoke<Visitor, R, Variant, Index>...
};
// 根据运行期的index选择调用哪个函数
return funcs.at(var.index())(vis, var);
}
template <typename Visitor, typename... Args>
auto visit(Visitor &&vis, std::variant<Args...> &&var) -> decltype(vis(std::get<0>(var))) {
using R = decltype(vis(std::get<0>(var)

文章介绍了C++模板元编程中的访问函数实现,包括visit_detail_invoke和visit_detail的辅助函数,以及visit主函数,展示了如何在编译期处理variant的所有情况。此外,文章探讨了模板范式的核心思想,通过对比OOP范式和模板范式的实现方式,阐述了模板范式倾向于在编译期确定更多事情的特点,并给出了一个使用模板判断类型是否包含特定方法的例子。最后,文章讨论了C++中模板元编程的优缺点以及实际开发中的应用考量。
最低0.47元/天 解锁文章
6065

被折叠的 条评论
为什么被折叠?



