2405C++,C++的变量

原文

试想,用std::variant<A,B,C>擦除了类型,然后按数格串``序化变量对象,这挺爽的,想序化A,B,C中,任意一个类型,只要赋值变量就行,代码不变,不用再写一份,这用起来确实挺爽.

但是,从数格串,反序化变量时怎么办,你怎么知道该数格串A还是B还是C呢?

然而,这就是社区同学对iguana提的一个需求,想序化和反序化都支持变量.

数格串,反序化到变量确实是个问题,但不是个大问题,可这样做:

试转换数格串变量中的每一个类型,直到成功为止,成功后把值赋给变量即可.

这样就需要一个遍历变量类型的功能了,同时还要注意,如果转换失败了,需要恢复数格串,再试下一次.看看iguana怎么序化和反序化变量的吧.

namespace my_space {
struct inner_struct {
  int x;
  int y;
  int z;
};
REFLECTION(inner_struct, x, y, z);
}  //my_space名字空间
struct nest_t {
  std::string name;
  my_space::inner_struct value;
  std::variant<int, std::string, double> var;
  std::variant<int, std::string, my_space::inner_struct> var2;
};
REFLECTION(nest_t, name, value, var, var2);
TEST_CASE("test variant") {
  std::variant<int, std::string, double> var;
  var = "test";
  nest_t v{"Hi", {1, 2, 3}, var, my_space::inner_struct{2, 4, 6}};
  std::string s;
  iguana::to_json(v, s);
  std::cout << s << std::endl;
  nest_t v2;
  iguana::from_json(v2, s);
  CHECK(v.var == v2.var);
}

测试表明iguana能正确反序化变量类型.接着具体来看看iguana是怎么序化和反序化变量的吧.

序化很简单,使用std::visit就行了:

template <bool Is_writing_escape, typename Stream, typename T, std::enable_if_t<variant_v<T>, int>>
IGUANA_INLINE void to_json_impl(Stream &s, T &&t) {
  std::visit(
      [&s](auto value) {
        to_json_impl<Is_writing_escape>(s, value);
      },
      t);
}

反序化就比较复杂了:

先取variant_size,然后根据该大小生成编译期索引列表,后面再根据std::get(variant)得到索引位置类型,然后试转换数格串该类型,编译期索引列表用来遍历变量所有类型.

template <size_t Idx, typename T>
using variant_element_t = std::remove_reference_t<decltype(std::get<Idx>(
    std::declval<std::remove_reference_t<T>>()))>; //#2
template <typename U, typename It, size_t... Idx>
IGUANA_INLINE void from_json_variant(U &value, It &it, It &end, std::index_sequence<Idx...>) {
  bool r = false;
  It temp_it = it;
  It temp_end = end;
  ((void)(!r && (r = from_json_variant_impl<
     variant_element_t<Idx, std::remove_reference_t<U>>>(
     value, it, end, temp_it, temp_end), true)),
   ...); //#3
  it = temp_it;
  end = temp_end;
}
template <typename U, typename It, std::enable_if_t<variant_v<U>, int> = 0>
IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) {
  from_json_variant(value, it, end, std::make_index_sequence< std::variant_size_v<std::remove_reference_t<U>>>{}); //#1
}

#1代码根据variant_size生成了编译期的索引序列,#2代码,根据编译期索引取对应类型,注意移除引用,因为std::get(variant)返回的是引用类型.

#3代码根据折叠式来把每个类型传入到from_json_variant_impl函数中,其实现:

template <typename value_type, typename U, typename It>
IGUANA_INLINE bool from_json_variant_impl(U &value, It it, It end, It &temp_it, It &temp_end) {
  try {
    value_type val;
    from_json_impl(val, it, end); //#4
    value = val;
    temp_it = it;
    temp_end = end;
    return true;
  } catch (std::exception &ex) {
    return false;
  }
}

#4代码会试转换数格串变量的某个类型,如果转换失败则会抛异常,则返回,成功返回,为何返回bool呢,因为需要保证转换成功后,后面不会重入到from_json_variant_impl函数中,具体是如何保证的呢?

再回过头来看#3代码.

bool r = false;
((void)(!r && (r = from_json_variant_impl<
         variant_element_t<Idx, std::remove_reference_t<U>>>(
         value, it, end, temp_it, temp_end),
     true)),
...);

最开始控制变量为,第一次肯定会进入到from_json_variant_impl,如果from_json_variant_impl返回,则逻辑与式左边结果,则整个式一定为,下次就不会再进入from_json_variant_impl函数中了;

如果from_json_variant_impl返回,则逻辑与式左边为,此时还需要依赖右边式结果才能知道是否为真,因此会继续进入from_json_variant_impl函数中.

另外一个方式是,把bool变量rfrom_json_variant_impl函数的出参,检查函数开头,如果发现它,按则不执行后面的代码,这样才能解决问题,但是会多次进入函数.

利用bool控制变量和逗号式,可很好控制是否需要进入from_json_variant_impl函数中,性能也会更好,虽然代码复杂了一些,但这已是性能最好了.

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

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

相关文章

tomcat篇-windows 运行tomcat的startup.bat时,终端打印的中文显示为乱码

当运行Tomcat的startup.bat时&#xff0c;如果终端中中文显示为乱码&#xff0c;这通常是因为Tomcat使用的日志输出编码与Windows命令行默认的编码不匹配。针对这一问题&#xff0c;你可以尝试以下步骤来解决&#xff1a; 1、执行startup.bat&#xff0c;在输出的窗口右击&…

Android --- 网络请求

通常在 Android 中进行网络连接一般使用 Scoket 和HTTP&#xff0c;HTTP 请求方式比 Scoket 多。HTTP 请求一般采用原生的 HttpClient 和 HttpUrlConnection 的两种网络访问方式&#xff08;系统自带的&#xff09;。但是在 Android 5.0 的时候 Google 就不推荐使用 HttpClient…

【限免】雷达目标生成与探测研究项目【附MATLAB代码】

文章来源&#xff1a;微信公众号&#xff1a;EW Frontier 课题背景 该项目的目标是模拟FMCW雷达检测运动目标&#xff0c;然后执行信号处理功能&#xff0c;以估计模拟目标的距离和多普勒速度。 图1&#xff1a;雷达模拟和检测的项目工作流程 FMCW波形设计 根据系统要求设计…

JAVA Coding 规范

Coding 规范 文章目录 Coding 规范一.文件规范1.1 声明1.2 缩进1.3 空行1.4 空格1.5 对齐1.6 小括号1.7 花括号1.8 代码长度 二.命名规范2.1 命名总则2.2 命名空间2.3 类与接口2.4 方法命名2.5 属性命名2.6 常量命名2.7 变量命名 三.语句规范3.1 语句总则3.2 循环语句3.3 Switc…

windows rabbitMq安装

一、Erlang 环境准备 下载安装包 跟我们跑java项目&#xff0c;要装jdk类似。rabbitMQ是基于Erlang开发的&#xff0c;因此安装rabbitMQ服务器之前&#xff0c;需要先安装Erlang环境。 官网直接下载windows直装版本&#xff1a;https://www.erlang.org/downloads 无脑安装&a…

【CGALDotNet】CGAL的C#封装(C#调用编译好的CGAL的dll)

介绍 开源项目出处&#xff08;两个模块&#xff09;&#xff1a; 链接1&#xff1a;https://github.com/Scrawk/CGALDotNet/tree/master?tabreadme-ov-file 链接2&#xff1a;https://github.com/Scrawk/CGALDotNetGeometry 该项目提供了编译的、封装相关接口后的CGAL库&am…

C语言 | Leetcode C语言题解之第62题不同路径

题目&#xff1a; 题解&#xff1a; int uniquePaths(int m, int n) {long long ans 1;for (int x n, y 1; y < m; x, y) {ans ans * x / y;}return ans; }

“Unite“ > MacOS下很不错的网站转应用App的工具

前言 前不久在浏览mac论坛&#xff0c;无意了解到一款非常好的工具&#xff0c;可以将网站转换为app&#xff0c;考虑到我们现在的主要应用都从本地客户端转成web形式使用&#xff0c;但基于本能的使用习惯&#xff0c;还是希望有个快捷的访问信息&#xff0c;这个应用非常适合…

万兆以太网MAC设计(11)完整UDP协议栈仿真

文章目录 前言一、模块接口二、IP模块与ARP模块之间的联系三、整体协议栈仿真总结&#xff1a; 前言 目前除了巨帧处理逻辑之外&#xff0c;所有的准备工作都已经结束了&#xff0c;先进行整体的功能验证。 一、模块接口 所有模块接口皆采用AXIS数据流的形式&#xff0c;其中…

IDEA基于Maven构建项目

IDEA基于Maven构建项目 一、Maven简介 Apache Maven 是一个软件项目管理和理解工具。基于项目对象模型的概念&#xff08;POM&#xff09;&#xff0c;Maven 可以从中心信息中管理项目的构建、报告和文档。 Apache Maven 可以用于构建和管理任何基于 Java 的项目。 下载地址…

【Web】D^3CTF之浅聊d3pythonhttp——TE-CL请求走私

目录 step0 题目信息 step1 jwt空密钥伪造 step1.5 有关TE&CL的lab step2 TE-CL请求走私 payload1 payload2 step0 题目信息 注意到题目源码前端是flask写的&#xff0c;后端是web.py写的 frontend from flask import Flask, request, redirect, render_templat…

C#核心之面向对象-封装

面向对象-封装 文章目录 1、类和对象1、什么是类2、类的声明3、类声明语法4、类声明实例5、对象(类)6、实例化对象语法7、实例化对象 2、成员变量和访问修饰符1、成员变量2、访问修饰符3、成员变量的使用和初始值 3、成员方法1、成员方法声明2、成员方法的使用 4、构造函数和…

【工具类安装教程】IDEA Ui设计器JFormDesigner

1、下载插件 File->Settings->Plugins->JFormDesigner 2、注册教程 2.1注册机下载 链接&#xff1a;https://pan.baidu.com/s/1Rb1EMva5HIYbyBcYgCxIsw 提取码&#xff1a;6666 2.2找到目录 1、找到idea目录 2.3进入plugins目录 找到在JFormDesigner文件夹下lib文…

使用Gitbook生成电子书

背景 《Google工程实践文档》相对原文Google’s Engineering Practices documentation &#xff0c;部分内容过时了。需要更新中文版&#xff0c;并使用Gitbook把Markdown文件转换成对应的PDF电子书。   上一次生成PDF电子书是5年前&#xff0c;当时生成电子书的环境早已不在…

jenkins汉化不完全问题解决

jenkins安装完Localization:Chinese(Simplified)中文语言包后&#xff0c;发现是出现汉化不完全或者部分汉化的情况&#xff0c;如下图&#xff1a; 解决方法&#xff1a; 启动命令中指定语言 -Duser.languageen_US.UTF-8 或者 -Duser.languageC.UTF-8原因分析&#xff1a;安…

用户中心(下)

文章目录 计划登录逻辑接口简单说明cookie和session写代码流程后端逻辑层控制层测试用户管理接口 前端简化代码对接后端代理 计划 开发完成后端登录功能 &#xff08;单机登录 > 后续改造为分布式 / 第三方登录&#xff09;✔开发后端用户的管理接口 &#xff08;用户的查询…

南方Southmap4.0 一体成图软件

SouthMap 4.0 新增行业应用模块&#xff0c;实用工具箱扩展7大工具&#xff0c;集结8大模块&#xff0c;共45种实用功能&#xff0c;为水利、电力、道路施工等多应用场景提供数据生产的一站式解决方案。 SouthMap 4.0 新增行业应用模块&#xff0c;实用工具箱扩展7大工具&#…

前端素材库

大家好我是苏麟 , 今天推荐一个前端素材库 . 官网 : iconfont-阿里巴巴矢量图标库 这期就到这里 , 下期见!

【docker】docker compose 搭建私服

安装 Docker Registry 创建目录 mkdir -pv /usr/local/docker/registrymkdir -pv /usr/local/docker/data 创建 docker-compose.yml文件 进入目录创建docker-compose.yml cd /usr/local/docker/registrytouch docker-compose.yml 编辑docker-compose.yml vim docker-compo…

探索洗牌算法的魅力与杨辉三角的奥秘:顺序表的实际运用

目录 目录 前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; 洗牌算法 准备工作 买一副牌 洗牌 发牌 测试整体 &#x1f3af;&#x1f3af;很重要的一点 杨辉三角 总结 前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ …
最新文章