当前位置: 首页 > news >正文

C++第三种异质集合 std::any方式实现

#include <type_traits>
#include <any>
#include <functional>
#include <iomanip>
#include <iostream>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <vector>
//any是编译期的异质集合,要显示指定处理的类型;我们可以记录每种类型的哈希值,实现运行期动态处理这样的异质集合
//这里我们根据类型信息的哈希值去bind每种类型的处理函数

//绑定器生成器
template<class T, class F>
inline std::pair<const std::type_index, std::function<void(std::any const&)>>
GeneratorBinder(F const& f)
{
	return {
		std::type_index(typeid(T)),
		[g = f](std::any const& a)
		{
			if constexpr (std::is_void_v<T>)
				g();
			else
				g(std::any_cast<T const&>(a));
		}
	};
}
//定义绑定器集合
static std::unordered_map<std::type_index, std::function<void(std::any const&)>> any_visitor
{
	//注册基本类型的处理函数
		GeneratorBinder<void>([] { std::cout << "{}"; }),
		GeneratorBinder<int>([](int x) { std::cout << x; }),
		GeneratorBinder<unsigned>([](unsigned x) { std::cout << x; }),
		GeneratorBinder<float>([](float x) { std::cout << x; }),
		GeneratorBinder<double>([](double x) { std::cout << x; }),
		GeneratorBinder<char const*>([](char const* s){ std::cout << std::quoted(s);})
};
//处理器
inline void process(const std::any& a)
{
	if (const auto it = any_visitor.find(std::type_index(a.type()));
		it != any_visitor.cend()) {
		it->second(a);
	}
	else {
		std::cout << "Unregistered type " << std::quoted(a.type().name());
	}
}

//注册器
template<class T, class F>
inline void registrar(F const& f)
{
	std::cout << "Register visitor for type "
		<< std::quoted(typeid(T).name()) << '\n';
	any_visitor.insert(to_any_visitor<T>(f));
}

auto main() -> int
{
	std::vector<std::any> va{ {}, 42, 123u, 3.14159f, 2.71828, "C++17", };

	std::cout << "{ ";
	for (const std::any& a : va) {
		process(a);
		std::cout << ", ";
	}
	std::cout << "}\n";

	process(std::any(0xFULL)); //未注册的类型
	std::cout << '\n';

	//注册操作
	registrar<unsigned long long>([](auto x) {
		std::cout << std::hex << std::showbase << x;
		});

	process(std::any(0xFULL)); //< OK : 0xf
	std::cout << '\n';

	return 0;
}

相关文章:

  • 【Mybatis-plus】在mybatis-plus中 if test标签如何判断 list不为空
  • 尝试在软考65天前开始成为软件设计师-计算机网络
  • Spring Boot 集成 Quartz 实现定时任务(Cron 表达式示例)
  • Qt窗口控件之对话框QDialog
  • 基线定位系统:长基线与超短基线的原理与应用
  • 归并排序的思路与实现
  • 【Vitis AIE】FPGA快速部署ConvNet 示例MNIST数据集
  • 植物来源药用天然产物的合成生物学研究进展-文献精读121
  • QT Quick(C++)跨平台应用程序项目实战教程 1 — 教程简介
  • python中所有内置类型
  • 一文了解 分布式训练
  • 开源ASR选择
  • 探索大模型的幻觉问题及其解决策略
  • FIT Framework 社区 v3.5.0-M1 版本发布
  • Copilot提示词库用法:调整自己想要的,记住常用的,分享该共用的
  • `docker commit`和`docker tag`
  • 各类神经网络学习:(三)RNN 循环神经网络(中集),同步多对多结构的详细解释
  • Nginx代理本机的443到本机的8080端口
  • 基于DeepSeek-R1 的RAG智能问答系统开发攻略
  • 数据结构之栈的2种实现方式(顺序栈+链栈,附带C语言完整实现源码)
  • 外交部亚洲司司长刘劲松向菲方严肃交涉
  • 这座“蚌埠住了”的城市不仅会接流量,也在努力成为文旅实力派
  • 新造古镇丨上海古镇朱家角一年接待164万境外游客,凭啥?
  • 公交公司须关注新出行需求:“单车巴士”能否常态化
  • 俄罗斯称已收复库尔斯克州
  • 演员孙俪:中年人没有脆弱的时间,学习胡曼黎不内耗