2405C++,编译期根据成员变量地址获取其名称

原文

最近根据iguana的一个需求,给iguana增加了一个特征,支持在编译期根据成员变量地址取其名字.
用法如下:

struct point_t {
  int x;
  double y;
};
REFLECTION(point_t, x, y);
void test_name_of() {
  constexpr auto s1 = iguana::name_of<&point_t::y>();
  static_assert(s1 == "y");
  constexpr auto s2 = iguana::name_of<&person::name>();
  static_assert(s2 == "name");
}

iguana可在编译期取反射类型串数组,如果能根据成员变量地址对应索引,则就可用索引数组中得到对应名字.

name_of的实现:

template <class T>
struct member_tratis {};
template <class T, class Owner>
struct member_tratis<T Owner::*> {
  using owner_type = Owner;
  using value_type = T;
};
template <auto member>
constexpr auto name_of() {
  using T = typename member_tratis<decltype(member)>::owner_type; //#1
  using M = Reflect_members<T>;
  constexpr auto s = M::arr()[index_of<member>()]; //#2
  return std::string_view(s.data(), s.size());
}

#1代码根据成员变量地址类型萃取出其父类型.
#2代码,index_of<member>()根据成员变量地址获得对应索引.index_of的实现:

template <auto member>
constexpr size_t index_of() {
  using namespace detail;
  using T = typename member_tratis<decltype(member)>::owner_type;
  using M = Reflect_members<T>;
  constexpr auto tp = M::apply_impl(); //#1
  constexpr size_t Size = std::tuple_size_v<decltype(tp)>;
  constexpr size_t index = member_index(member, tp); //#2
  static_assert(index < Size, "out of range");
  return index;
}

index_of的实现思路是,遍历反射类型所有成员变量地址生成的元组,然后判断,如果给定成员变量地址元组中的某个元素相等,则返回该索引.

#1代码,在编译期获得反射类型所有成员变量地址元组,#2代码调用member_index得到对应索引.member_index的实现:

template <typename T, typename U>
constexpr bool get_index_imple(T ptr, U ele) {
  if constexpr (std::is_same_v< typename iguana::member_tratis<decltype(ptr)>::value_type, typename iguana::member_tratis< decltype(ele)>::value_type>) {
    if (ele == ptr) {
      return true;
    }
    else {
      return false;
    }
  }
  else {
    return false;
  }
}
template <typename T, typename Tuple, size_t... I>
constexpr size_t member_index_impl(T ptr, Tuple &tp, std::index_sequence<I...>) {
  bool r = false;
  size_t index = 0;
  ((void)(!r && (r = get_index_imple(ptr, std::get<I>(tp)), !r ? index++ : index, true)),
   ...);
  return index;
}
template <typename T, typename Tuple>
constexpr size_t member_index(T ptr, Tuple &tp) {
  return member_index_impl(
      ptr, tp,
      std::make_index_sequence<
          std::tuple_size_v<std::decay_t<decltype(tp)>>>{});
}

member_index_impl函数中遍历元组,然后折叠式调用get_index_imple检查给定成员变量地址ptr元组中的元素的地址是否相等,如果相等则index++,否则索引不变,如果检查地址相等,则后面不会再进入get_index_imple函数.

最终遍历元组可在编译期获得成员变量对应的索引,有了该索引就能从编译期数组中取对应字段名.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/588905.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes - Dashboard 配置用户名密码方式登录

Kubernetes - Dashboard 配置用户名密码方式登录 前言&#xff1a; 为了 K8s 集群安全&#xff0c;默认情况下 Dashboard 以 Token的形式登录的&#xff0c;那如果我们想以用户名/密码的方式登录该怎么操作呢&#xff1f;其实只需要我们创建用户并进行 ClusterRoleBinding绑定即…

挑战一周完成Vue3项目Day4: 用户管理+角色管理+菜单管理+首页+暗黑模式/主题切换

一、用户管理 1.静态搭建 src/views/acl/user/index.vue <template><el-card style"height:80px;"><el-form :inline"true" class"form"><el-form-item label"用户名&#xff1a;"><el-input placehold…

JAVA面试专题-微服务篇

Spring cloud Spring Cloud 5大组件有哪些 注册中心/配置中心&#xff1a;nacos 负载均衡&#xff1a;Ribbon 服务远程调用&#xff1a;Feign 服务保护&#xff1a;sentinel 服务网关&#xff1a;Gateway 微服务注册和发现 nacos和eureka的区别 负载均衡 微服务向Ribbon发送…

Vue 之 在当前页面的实现分页效果

目录 场景实现 场景 假设&#xff0c;我们现在有这么一个需求&#xff1a; 上述图片的空白内容是活动的&#xff0c;由下面的两个按钮控制上一页、下一页&#xff1b;我们应该可以怎么去实现&#xff1f; 实现 思路&#xff1a; 其实这个问题&#xff0c;我们仿照其他的UI框…

数字旅游以科技创新为动力:推动旅游服务的智能化、网络化和个性化发展,满足游客日益增长的多元化、个性化需求

目录 一、引言 二、科技创新推动旅游服务智能化发展 1、智能化技术的引入与应用 2、智能化提升旅游服务效率与质量 三、科技创新推动旅游服务网络化发展 1、网络化平台的构建与运营 2、网络化拓宽旅游服务渠道与范围 四、科技创新推动旅游服务个性化发展 1、个性化需求…

Sortable 拖拽行实现el-table表格顺序号完整例子,vue 实现表格拖拽行顺序号完整例子

npm install sortable<template><vxe-modalref"modalRef"v-model"showModal"title"详情"width"70vw"height"60vh"class"his"transfer><el-table ref"tableRef" :data"tableData&q…

mysql从入门到起飞+面试基础题

mysql基础 MySQL基础 企业面试题1 代码 select m.id,m.num from ( select t.id as id,count(1) num from ( select ra.requester_id as id from RequestAccepted raunion all select ra.accepter_id as id from RequestAccepted ra ) t group by t.id ) m group by id ord…

鸿蒙原生应用元服务开发-Web加载本地页面

将本地页面文件放在应用的rawfile目录下&#xff0c;开发者可以在Web组件创建的时候指定默认加载的本地页面 &#xff0c;并且加载完成后可通过调用loadUrl()接口变更当前Web组件的页面。 在下面的示例中展示加载本地页面文件的方法&#xff1a; 将资源文件放置在应用的resou…

HarmaonyOS鸿蒙应用科普课

一、什么是鸿蒙OS&#xff1f; 1.概念&#xff1a; 先给大家讲讲今天讲课的主题&#xff0c;鸿蒙OS是什么&#xff1f;鸿蒙系统大家都知道&#xff0c;就是一个操作系统&#xff0c;我们未来是为的成为鸿蒙程序员。所以我们不要将鸿蒙os完全等同于手机操作系统&#xff0c;太…

C#技巧之同步与异步

区别 首先&#xff0c;同步就是程序从上往下顺序执行&#xff0c;要执行完当前流程&#xff0c;才能往下个流程去。 而异步&#xff0c;则是启动当前流程以后&#xff0c;不需要等待流程完成&#xff0c;立刻就去执行下一个流程。 同步示例 创建一个窗体&#xff0c;往窗体里…

Python_GUI框架 Pyside6的信号与槽应用

Python_GUI框架 Pyside6的信号与槽应用 在Pyside6框架中&#xff0c;信号与槽&#xff08;Signals and Slots&#xff09;机制是连接用户界面元素与响应功能的核心机制。我们可以把信号想象成一根电线&#xff0c;而槽就是电线的另一端连接的灯泡。当电线&#xff08;信号&…

贪心算法 Greedy Algorithm

1) 贪心例子 称之为贪心算法或贪婪算法&#xff0c;核心思想是 将寻找最优解的问题分为若干个步骤 每一步骤都采用贪心原则&#xff0c;选取当前最优解 因为没有考虑所有可能&#xff0c;局部最优的堆叠不一定让最终解最优 v2已经不会更新v3因为v3更新过了 贪心算法是一种在…

第八篇:隔离即力量:Python虚拟环境的终极指南

隔离即力量&#xff1a;Python虚拟环境的终极指南 1 引言 在编程的多元宇宙中&#xff0c;Python语言犹如一颗闪耀的星辰&#xff0c;其魅力不仅仅在于简洁的语法&#xff0c;更在于其庞大而繁荣的生态系统。然而&#xff0c;随着应用的增长和复杂性的提升&#xff0c;开发者们…

WinRAR经典压缩神器,高效管理您的文件烈火汉化版 v7.0.

01 软件介绍 WinRAR&#xff0c;作为一款历史悠久且广为人知的压缩文件管理工具&#xff0c;已经成为压缩软件行业的标杆产品。其提供的完整支持覆盖了RAR和ZIP文件格式&#xff0c;同时&#xff0c;该软件还拥有诸多强大的解压缩功能&#xff0c;包括但不限于固体压缩、分卷压…

链表面试题2

1&#xff0c;合并两个有序链表 我们先定义一个虚拟节点newH&#xff0c; 然后按照上图所走&#xff0c;但是当其中一个链表走空时&#xff0c;我们只需返回另一个链表即可 class Solution {public ListNode mergeTwoLists(ListNode headA, ListNode headB) {ListNode newhead…

【C++】滑动窗口:长度最小的子数组

1.题目 2.算法分析 这种题目&#xff0c;首先想到的是暴力穷举法&#xff1a; 用两层循环取遍该数组的所有子数组&#xff0c;然后找到那个最短的就可以了。 我们的滑动窗口就是对这种暴力穷举法进行优化&#xff1a; 主要是舍弃的思想&#xff0c;舍弃那些一定不可能是最终…

03_电子设计教程基础篇(软件推荐)

文章目录 前言一、通用工具软件1.输入法2.截图3.录屏4.桌面管理5.文件检索6.笔记整理7.翻译软件8.AI软件9.文件对比10.思维导图、流程框图、表格软件11.项目托管平台12.解压缩软件13.休闲娱乐软件 二、专业工具软件1.硬件工程师1.原理图、PCB设计2.原理图、PCB仿真3.PCB下单软件…

DNS、ICMP、NAT以及代理服务器

目录 1. DNS 1.1. DNS 背景 1.2. 域名简介 1.3. 域名解析过程 2. ICMP 2.1. ICMP 的功能 2.2. ICMP 的报文格式 2.3. ping 命令 2.4. traceroute 命令 3. NAT和代理服务器 3.1. NAT 技术 3.2. NAT IP转换过程 3.3. NAT 技术的缺陷 3.4. 代理服务器 3.4.1. 正向…

界面组件DevExpress Blazor UI v23.2 - 网格、工具栏功能全新升级

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验&#xff0c;这个UI自建库提供了一套全面的原生Blazor UI组件&#xff08;包括Pivot Grid、调度程序、图表、数据编辑器和报表等&#xff09;。 DevExpress Blazor控件目前已经升级…

通信接口——时钟和信号

前言 所有接口只要抓住三个核心点就能分清&#xff1a;时钟同步和异步&#xff0c;时钟的来源&#xff0c;信号的传输方向。 一、时钟同步和异步 接口之间的交互方式存在多种形式&#xff0c;如果按照是否有公共时钟CLK的参与&#xff0c;可以分为同步传输和异步传输。 同步&…
最新文章