深入C++反射与元组

首先最近比较火的元宇宙,我谈谈个人观点:元宇宙的实现,只能是系统级的语言。举例就谈下c++的元组tuple,因为元组可用作反射0开销的最佳方式,所以觉得构建元宇宙必少不了tuple元组。

元组的用途

  1. 实现类型列表
  2. 给结构体属性加索引以便拥有下标进行赋值
  3. 解决了无法动态获取结构体属性(以往就只能靠点属性,但很难知道属性名)
  4. 可以静态过滤结构体中的某些类型,实现类型过滤
  5. 允许静态编译期萃取结构体的某个类型(一般不用于基本类型)
  6. 结合类型萃取和模板技术,可以编译期枚举所有可能的类型情况

元组的本质

  • 实际上std::tuple与结构体或者class有着一定的联系
  • 拿class举例,class T; 假设T的第一属性是int类型的id,那么&T::id就类似于一个属于T的指针
  • 如果T t; 那么 t->*&T::id 就等同于 t.id 也等同于 t->*std::get<0>(std::tuple<int T::*>)
  • 结合reinterpret_cast可以做强转,在不知道属性名的情况下拿到offset偏移量来直接赋值
  • *((char*)(reinterpret_cast<char*>(t)+(size_t)(&reinterpret_cast<char const volatile&>(((T*)0)->*std::get<0>(std::tuple<int T::*>)))))也就是隐式拿到了t.id【这里具体例子请在最后链接看】
//首先编译期判断类型是否正确
constexpr int count_first_falses() { return 0; }
template <typename... B> constexpr int count_first_falses(bool b1, B... b) {
  if (b1) return 0; else return 1 + count_first_falses(b...);
}

我们采用count_first_falses在编译期判断B参数包到底是不是我们想要的类型,返回一个索引

再实现type_get函数,来进行编译期元组的萃取指定类型的值,返回的是该类型的值

//实现左值和右值两个版本的type_get函数
template <typename E, typename... T> decltype(auto) type_get(std::tuple<T...>& tuple) {
  typedef std::decay_t<E> DE;
  return std::get<count_first_falses((std::is_same<std::decay_t<T>, DE>::value)...)>(tuple);
}
template <typename E, typename... T> decltype(auto) type_get(std::tuple<T...>&& tuple) {
  typedef std::decay_t<E> DE;
  return std::get<count_first_falses((std::is_same<std::decay_t<T>, DE>::value)...)>(tuple);
}

tuple_filter可以过滤掉元组中的某一种类型的全部,返回的是一个元组


                
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值