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

网站建设及相关流程dede游戏网站源码

网站建设及相关流程,dede游戏网站源码,一等一网站,网站开发与维护的相关大学在现代C的发展中,新引入的语言特性为高效且易用的序列化和反序列化库的开发提供了强大的支持。我们今天一起来探索如何在现代C特性下写出更简洁、更易维护的序列化工具代码。 现有序列化库的挑战 传统的C序列化库,如Boost.Serialization和Cereal&#…

在现代C++的发展中,新引入的语言特性为高效且易用的序列化和反序列化库的开发提供了强大的支持。我们今天一起来探索如何在现代C++特性下写出更简洁、更易维护的序列化工具代码。

现有序列化库的挑战

传统的C++序列化库,如Boost.Serialization和Cereal,虽然功能强大,但通常需要额外的设置步骤,如显式注册类和成员,或依赖于预处理器命令。这些需求增加了使用的复杂性,并可能导致代码依赖于特定的编译器特性或外部工具。

截止至C++20,我们实现序列化的可选方案有:

要实现一流的序列化工具,我们要依赖一些非标准的技术或库来在编译期遍历结构体成员。以下是一些方法:

  1. 模板递归与特化: 通过模板递归和特化技术,你可以在编译期迭代结构体的成员,尤其是当你可以定义一些辅助模板结构来存储成员信息时。例如,你可以使用模板结构来存储成员的类型和名称,然后递归地处理这些模板结构。

  2. C++20结构化绑定: 尽管这不是直接遍历所有成员的方法,结构化绑定可以让你更容易地解构结构体,配合模板和constexpr编程,可以部分实现在编译期处理结构体成员的目的。

接下来,我们尝试用这两个技术实现一个系列化库:

模板递归与特化

使用模板递归和特化技术来在编译期迭代结构体的成员涉及到一些高级的C++模板编程技巧。

#include <iostream>
#include <tuple>// 基本的模板,用于存储成员的信息,即成员的访问器
template<typename T, typename Class, T Class::*Member>
struct MemberInfo {using Type = T;static constexpr T Class::* pointer = Member;
};// 结构体,我们想要遍历其成员
struct MyStruct {int a;double b;char c;
};// 成员信息的定义
using Members = std::tuple<MemberInfo<int, MyStruct, &MyStruct::a>,MemberInfo<double, MyStruct, &MyStruct::b>,MemberInfo<char, MyStruct, &MyStruct::c>
>;// 递归模板来遍历成员信息
template<std::size_t I, std::size_t N>
struct IterateMembers {static void execute(const MyStruct& s) {using Member = std::tuple_element_t<I, Members>;std::cout << "Member " << I << " value: " << s.*(Member::pointer) << std::endl;IterateMembers<I + 1, N>::execute(s);}
};// 特化,停止递归
template<std::size_t N>
struct IterateMembers<N, N> {static void execute(const MyStruct&) {}
};int main() {MyStruct s = {10, 3.14, 'z'};IterateMembers<0, std::tuple_size<Members>::value>::execute(s);return 0;
}

在这个示例中,我们定义了一个名为MemberInfo的模板结构,它可以存储对结构体成员的引用。我们创建了一个名为MyStruct的示例结构体,它包含几个不同类型的成员。为每个成员定义了MemberInfo实例,并将它们存储在std::tuple中。

IterateMembers模板用于递归地访问这个元组中的每个成员。递归在达到元组的末尾时通过模板特化停止。

这个程序将输出MyStruct实例s的每个成员的值。这是一个静态的方式,因为所有的成员必须在编译时被明确指定。这种方法在成员数量和类型在编译时已知的情况下非常有用,但它不具备通用反射机制的灵活性。

这个示例将使用模板特化和递归模式,但这种方法依赖于手动定义一些模板辅助结构来存储关于结构体成员的信息。这不是自动反射,而是一种静态的方式来模拟反射的功能。

C++20结构化绑定

为了使用C++20的结构化绑定特性来在编译期处理结构体成员,我们可以结合使用结构化绑定、模板元编程以及constexpr函数。虽然结构化绑定本身不提供直接遍历所有成员的功能,但我们可以使用它来简化对结构体成员的访问,并结合模板来进行编译期的操作。

下面示例展示如何结合使用C++20的结构化绑定和模板来处理结构体:

#include <iostream>
#include <tuple>
#include <type_traits>// 定义一个简单的结构体
struct MyStruct {int intValue;double doubleValue;char charValue;
};// 一个constexpr函数,用于根据类型打印不同的信息
template<typename T>
constexpr void printValue(const T& value) {if constexpr (std::is_same_v<T, int>) {std::cout << "Int: " << value << std::endl;} else if constexpr (std::is_same_v<T, double>) {std::cout << "Double: " << value << std::endl;} else if constexpr (std::is_same_v<T, char>) {std::cout << "Char: " << value << std::endl;}
}// 使用结构化绑定和模板递归处理每个成员
template<typename... Args, std::size_t... Is>
constexpr void processMembers(const std::tuple<Args...>& tpl, std::index_sequence<Is...>) {(printValue(std::get<Is>(tpl)), ...);
}int main() {MyStruct s{42, 3.14, 'c'};// 使用结构化绑定来创建一个tuple,这个tuple拥有MyStruct的所有成员auto [intValue, doubleValue, charValue] = s;// 将成员封装成tuple,并使用index_sequence来遍历每个元素auto tuple = std::make_tuple(intValue, doubleValue, charValue);processMembers(tuple, std::make_index_sequence<std::tuple_size<decltype(tuple)>::value>{});return 0;
}

在这个示例中,我们定义了一个MyStruct结构体,它包含三个不同类型的成员。我们使用结构化绑定来解构这个结构体并得到一个tuple。然后我们定义了一个printValue函数模板,它使用if constexpr来在编译期根据类型选择如何打印每个成员的值。

最后,在main函数中,我们使用结构化绑定来创建一个包含所有成员的tuple,并使用一个模板函数processMembers来遍历并处理这个tuple中的每个成员。我们使用std::index_sequence来生成一个编译期的索引序列,这允许我们在编译期展开对每个成员的处理。

虽然这个示例并没有直接遍历结构体的成员,它展示了如何使用结构化绑定来简化成员的访问并结合模板和constexpr来进行编译期计算。这种方法在处理已知结构体时非常有用,可以有效地利用C++20的新特性进行编译期优化。

但是,需要使用者在使用时每次都将结构体转换为结构化绑定,即:

	MyStruct s{42, 3.14, 'c'};// 使用结构化绑定来创建一个tuple,这个tuple拥有MyStruct的所有成员auto [intValue, doubleValue, charValue] = s;    // 将成员封装成tuple,并使用index_sequence来遍历每个元素auto tuple = std::make_tuple(intValue, doubleValue, charValue);processMembers(tuple, std::make_index_sequence<std::tuple_size<decltype(tuple)>::value>{});

这样依然很不优雅。

我们可以把结构化绑定的代码,通过某种形式转移到结构体声明中去,这样就能避免每次序列化和反序列化写结构化绑定的代码了:

#include <iostream>
#include <tuple>
#include <sstream>#define TO_TUPLE(...) auto toTuple() { return std::tie(__VA_ARGS__); }struct Person {std::string name;int age;TO_TUPLE(name, age)  // 使用宏来简化tuple的生成
};template<typename T>
std::string serialize(T& data) {auto tuple = data.toTuple();std::ostringstream oss;std::apply([&oss](auto&&... args) {((oss << args << " "), ...);}, tuple);return oss.str();
}template<typename T>
T deserialize(const std::string& s) {T data; // 创建一个新的T类型的实例auto tuple = data.toTuple(); // 获取成员的tuplestd::istringstream iss(s);std::apply([&iss](auto&&... args) {((iss >> args), ...); // 读取每个成员}, tuple);return data; // 返回填充好的数据结构
}int main() {Person p{ "Alice", 30 };std::string serialized = serialize(p);std::cout << "Serialized: " << serialized << std::endl;Person deserialized = deserialize<Person>(serialized);std::cout << "Deserialized: " << deserialized.name << ", " << deserialized.age << std::endl;
}

在这里插入图片描述
上面代码中,虽然还需要在结构体里声明TO_TUPLE,但是相比前面两个实现,在设计上已经非常友好了。
对于自定义类型,通过stringstream的重载即可支持序列化操作,不再冗述。

在现有的C++技术中,不依赖外部工具,也只能做到这一步。无法省略结构体的TO_TUPLE,而且无法可靠地检测出开发者是否存在漏写的情况。

实际上,上述代码在支持C++17的环境中即可正常运行,不需要C++20。

展望未来C++标准实现反射库

在C++ 26有关反射的提案,用提案中的方法,可以方便地遍历结构体的成员:

struct S { unsigned i:2, j:6; };
consteval auto member_number(int n) {if (n == 0) return ^S::i;else if (n == 1) return ^S::j;
}int main() {S s{0, 0};s.[:member_number(1):] = 42;  // Same as: s.j = 42;s.[:member_number(5):] = 0;   // Error (member_number(5) is not a constant).
}

类似地,很容易将结构体的所有成员转换为元组,从而省略我们最终方法中的依赖在结构体声明TO_TUPLE的限制了。

结语

随着C++标准的不断进化,实现简洁又实用的序列化工具变得越来越简单。
目前我们还无法完全实现对结构体无侵入地实现反射,但是未来即将可以轻松实现。


文章转载自:

http://s8iMVRwq.wkmpx.cn
http://J8PbB5lc.wkmpx.cn
http://Y9dlK9rG.wkmpx.cn
http://3W8q3E4x.wkmpx.cn
http://5UnN8gnJ.wkmpx.cn
http://b6IwAm8U.wkmpx.cn
http://wR1PJKAW.wkmpx.cn
http://NuDamukS.wkmpx.cn
http://YV4v6nLR.wkmpx.cn
http://5q1JHUhC.wkmpx.cn
http://jTWMS9lj.wkmpx.cn
http://gPXlrF8D.wkmpx.cn
http://s2m41jk5.wkmpx.cn
http://duTwUcde.wkmpx.cn
http://gQIyvLQ7.wkmpx.cn
http://gu49Ad3P.wkmpx.cn
http://bUyjjghS.wkmpx.cn
http://FT3KS0OD.wkmpx.cn
http://ap9Kyng9.wkmpx.cn
http://I0c0Rzik.wkmpx.cn
http://ilbQDz3b.wkmpx.cn
http://hCewO6Nk.wkmpx.cn
http://5rFujETT.wkmpx.cn
http://EzJFY3hl.wkmpx.cn
http://Bouof5xd.wkmpx.cn
http://Ki9lpw4C.wkmpx.cn
http://AFWOGk9I.wkmpx.cn
http://I3eM0YSO.wkmpx.cn
http://mtMyceIj.wkmpx.cn
http://uxkBKWPm.wkmpx.cn
http://www.dtcms.com/wzjs/743927.html

相关文章:

  • 建设银行网站账号怎么注销网站的栏目管理
  • 丰台区建设网站全国统一核酸检测价格
  • 网站首页新闻模板seo怎么做排名
  • 哪个网站是做安全教育wordpress 中文版 编码
  • 做汽车配件出口用什么网站好些昆山城市建设网站
  • 免费注册qq号网站wordpress文件上传位置
  • 北京沙河教做网站的长春什么时候解封
  • 网站制作技术有哪些蚂蚁币是什么网站建设
  • 网站建设好学吗长沙大型网站设计公司
  • 山东建站北京网站名称注册证书
  • 网站侧面的虚浮代码专业做互联网招聘的网站
  • 可以做软件外包项目的网站中信建设有限责任公司薛松
  • 与网站建设关系密切的知识点一般做公司网站需要哪几点
  • php部署网站番禺人才网入库考试
  • 如何更好的建设和维护网站wordpress数据库详解
  • 个人网站做cpa建设部网站官网查询
  • 茶山网站仿做易企秀h5制作官网
  • 图书网站开发数据库的建立怎么提高网站百度权重
  • 阿里云服务器发布网站网站文字广告代码
  • wordpress建站论坛阿里巴巴网站被关闭了要怎么做
  • 电商网站开发主要的三个软件西安seo引擎搜索优化
  • 游戏网站怎么制作郑州推广优化公司
  • 手机怎样创建网站上海营业执照查询网上查询
  • 接网站做项目赚钱吗网站中如何做图片轮播
  • 在线考试系统网站模板做谷歌推广一定要网站吗
  • 酒泉市住房和城乡建设局网站工程建设标准
  • 长沙好的设计公司百度seo搜索引擎优化厂家
  • 机械设备asp企业网站源码下载wordpress plugins权限
  • 沙县建设局网站长春网站排名优化价格
  • 深圳快速网站制甘肃兰州地震最新消息