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

南昌网站设计公司海南营销网站建设

南昌网站设计公司,海南营销网站建设,wordpress轻论坛主题,网站建设编码相关系列文章 C三剑客之std::any(一) : 使用 C之std::tuple(一) : 使用精讲(全) C三剑客之std::variant(一) : 使用 C三剑客之std::variant(二)#xff1a;深入剖析​​​​​​​ 目录 1.概述 2.构建方式 2.1.构造函数 2.2.std::make_any 2.3.operator分配新值 3.访问值… 相关系列文章 C三剑客之std::any(一) : 使用 C之std::tuple(一) : 使用精讲(全) C三剑客之std::variant(一) : 使用 C三剑客之std::variant(二)深入剖析​​​​​​​ 目录 1.概述 2.构建方式 2.1.构造函数 2.2.std::make_any 2.3.operator分配新值 3.访问值std::any_cast 4.修改器 4.1.emplace 4.2.reset 4.3.swap 5.观察器 5.1.has_value 5.2.type 6.总结 1.概述 C17的三剑客分别是std::optional, std::any, std::vairant。今天主要讲std::any。std::any类用于任何可拷贝构造类型的单个值的类型安全容器。在头文件any中c标准库定义了类std::any。 namespace std { class any; } 从上面的定义可以看出std::any不是模版类而是一种很特殊的容器它只能容纳一个元素但这个元素可以是任意的类型可以是基本数据类型intdoublecharfloat...也可以是复合数据类型类、结构体。 std: any是一种值类型它能够更改其类型同时仍然具有类型安全性。也就是说对象可以保存任意类型的值但是它们知道当前保存的值是哪种类型。在声明此类型的对象时不需要指定可能的类型。 2.构建方式 2.1.构造函数 默认情况下std::any的初始值为空。如 std::any a; 也可以赋初值初始化对象std::any, 如 std::any a 32; //type: int std::any b wegrthweg; type : const chr* 要保存与初始值类型不同的类型必须使用in_place_type标记 std::any a{std::in_place_typeint, 420}; std::any b{std::in_place_typestd::string, asdfbsrghtr34}; 即使传递给in_place_type的类型也会退化。下面的声明包含一个const char*: std::any a{std::in_place_typeconst char[6], 12345}; 要通过多个参数初始化可选对象必须创建该对象或将std::in_place_type添加为第一个参数(不能推断包含的类型): std::any a1{std::complex{6.0, 2.0}}; std::any a2{std::in_place_typestd::complexdouble, 6.0, 2.0}; 甚至可以传递一个初始化器列表后面跟着附加的参数: auto func [] (int x, int y) { return std::abs(x) std::abs(y);};std::any a{std::in_place_typestd::setint,decltype(func), {3, 7, -1, -16, 1, 100}, func}; 2.2.std::make_any std::make_any的定义如下 //[1] template class T, class... Args std::any make_any( Args... args ); //[2] template class T, class U, class... Args std::any make_any( std::initializer_listU il, Args... args ); 构造含 T 类型对象的 any 对象传递提供的参数给 T 的构造函数。 1) 等价于 return std::any(std::in_place_typeT, std::forwardArgs(args)...); 2) 等价于 return std::any(std::in_place_typeT, il, std::forwardArgs(args)...); std::make_any必须显式指定初始化的类型(如果只传递一个参数则不会推导出初始化的类型)如 #include any #include complex #include functional #include iostream #include stringint main() {auto a0 std::make_anystd::string(Hello, std::any!\n);auto a1 std::make_anystd::complexdouble(0.1, 2.3);std::cout std::any_caststd::string(a0);std::cout std::any_caststd::complexdouble(a1) \n;using lambda std::functionvoid(void);// 把 lambda 放入 std::any。尝试 #1 失败。std::any a2 [] { std::cout Lambda #1.\n; };std::cout a2.type() \ a2.type().name() \\n;// any_cast 转型到 void(void) 但实际类型不是// std::function ……而是 ~ main::{lambda()#1} 且它对// 每个 lambda 唯一。所以这会抛出……try {std::any_castlambda(a2)();}catch (std::bad_any_cast const ex) {std::cout ex.what() \n;}// 将 lambda 放入 std::any 中。尝试 #2 成功auto a3 std::make_anylambda([] { std::cout Lambda #2.\n; });std::cout a3.type() \ a3.type().name() \\n;std::any_castlambda(a3)(); } 输出 Hello, std::any! (0.1,2.3) a2.type() Z4mainEUlvE_ bad any_cast a3.type() St8functionIFvvEE Lambda #2. 2.3.operator分配新值 operator的定义如下 //[1] any operator( const any rhs ); //[2] any operator( any rhs ) noexcept; //[3] templatetypename ValueType any operator( ValueType rhs );1) 通过复制 rhs 的状态赋值如同用 any(rhs).swap(*this)。 2) 通过移动 rhs 的状态赋值如同用 any(std::move(rhs)).swap(*this)。赋值后 rhs 留在有效但未指定的状态。 3) 以 rhs 的类型和值赋值如同用 any(std::forwardValueType(rhs)).swap(*this)。此重载只有在 std::decay_tValueType 与 any 不是同一类型且 std::is_copy_constructible_vstd::decay_tValueType 为 true 时才会参与重载决议。std::decay_tValueType 必须满足可复制构造条件。示例如下 std::any a 1223; std::any b 2222222; a b; //[1] b 6.34655; //[3] a std::make_anystd::complex(6.0, 2.0); //[2]上面代码执行a b调用的是第1个赋值函数b6.34655调用的是第3个赋值函数a std::make_anystd::complex(6.0, 2.0) 是调用的第2个赋值函数。 3.访问值std::any_cast std::any_cast的定义 //[1] template class T T any_cast( const any operand ); //[2] template class T T any_cast( any operand ); //[3] template class T T any_cast( any operand ); //[4] template class T const T* any_cast( const any* operand ) noexcept; //[5] template class T T* any_cast( any* operand ) noexcept; 要访问包含的值必须使用std::any_cast将其转换为其类型。将该值转换为一个字符串有几个选项:  std::any_caststd::string(a) // yield copy of the value std::any_caststd::string(a); // write value by reference std::any_castconst std::string(a); // read-access by reference 在这里如果转换失败将抛出std::bad_any_cast异常。因此在不检查或不知道类型的情况下最好实现以下功能:  try {auto s std::any_caststd::string(a);... } catch (std::bad_any_cast e) {std::cerr EXCEPTION: e.what() \n; } 注意std::any_cast创建了一个传递类型的对象。如果将std::string作为模板参数传递给std::any_cast它将创建一个临时string(一个prvalue)然后用它初始化新对象。如果没有这样的初始化通常最好转换为引用类型以避免创建临时对象: std::cout std::any_castconst std::string(a); 要修改该值需要转换为对应的引用类型: std::any_caststd::string(a) 2134y56; 根据上面的第4或5个转换函数定义还可以为std::any对象的地址调用std::any_cast。在这种情况下如果类型匹配则强制转换返回相应的地址指针;如果不匹配则返回nullptr: auto p std::any_caststd::string(a); if (p) {... } 下面再看一个例子 #include any #include iostream #include string #include type_traits #include utilityint main() {// 简单示例auto a1 std::any(12);std::cout 1) a1 是 int std::any_castint(a1) \n;try{auto s std::any_caststd::string(a1); // 抛出}catch (const std::bad_any_cast e){std::cout 2) e.what() \n;}// 指针示例if (int* i std::any_castint(a1))std::cout 3) a1 是 int *i \n;else if (std::string* s std::any_caststd::string(a1))std::cout 3) a1 是 std::string *s \n;elsestd::cout 3) a1 是另一类型或者没有设置\n;// 进阶示例a1 std::string(hello);auto ra std::any_caststd::string(a1); // 引用ra[1] o;std::cout 4) a1 是字符串 std::any_caststd::string const(a1) \n; // const 引用auto s1 std::any_caststd::string(std::move(a1)); // 右值引用// 注意“s1” 是移动构造的 std::stringstatic_assert(std::is_same_vdecltype(s1), std::string);// 注意“a1” 中的 std::string 被置于合法但未指定的状态std::cout 5) a1.size() std::any_caststd::string(a1)-size() // 指针 \n 6) s1 s1 \n; } 输出 1) a1 是 int12 2) bad any_cast 3) a1 是 int12 4) a1 是 stringhollo 5) a1.size()0 6) s1hollo 4.修改器 4.1.emplace 更改所含对象直接构造新对象示例如下 #include algorithm #include any #include iostream #include string #include vectorclass Star {std::string name;int id;public:Star(std::string name, int id) : name { name }, id { id }{std::cout Star::Star(string, int)\n;}void print() const{std::cout Star{ \ name \ : id };\n;} };auto main() - int {std::any celestial;// (1) emplace( Args... args );celestial.emplaceStar(Procyon, 2943);const auto* star std::any_castStar(celestial);star-print();std::any av;// (2) emplace( std::initializer_listU il, Args... args );av.emplacestd::vectorchar({ C, , , 1, 7 } /* 无参数 */ );std::cout av.type().name() \n;const auto* va std::any_caststd::vectorchar(av);std::for_each(va-cbegin(), va-cend(), [](char const c) { std::cout c; });std::cout \n; } 输出 Star::Star(string, int) Star{ Procyon : 2943 }; St6vectorIcSaIcEE C17 4.2.reset 销毁所含对象。 4.3.swap 交换两个std::any。 5.观察器 5.1.has_value 检查对象是否含有值若实例含值则为 true 否则为 false 。示例如下 #include any #include iostream #include stringint main() {std::boolalpha(std::cout);std::any a0;std::cout a0.has_value(): a0.has_value() \n;std::any a1 42;std::cout a1.has_value(): a1.has_value() \n;std::cout a1 std::any_castint(a1) \n;a1.reset();std::cout a1.has_value(): a1.has_value() \n;auto a2 std::make_anystd::string(Milky Way);std::cout a2.has_value(): a2.has_value() \n;std::cout a2 \ std::any_caststd::string(a2) \\n;a2.reset();std::cout a2.has_value(): a2.has_value() \n; } 输出 a0.has_value(): false a1.has_value(): true a1 42 a1.has_value(): false a2.has_value(): true a2 Milky Way a2.has_value(): false 5.2.type 查询所含类型若实例非空则为所含值的 typeid 否则为 typeid(void) 。示例如下 #include type_traits #include any #include functional #include iomanip #include iostream #include typeindex #include typeinfo #include unordered_map #include vectortemplateclass T, class F inline std::pairconst std::type_index, std::functionvoid(std::any const)to_any_visitor(F const f) {return {std::type_index(typeid(T)),[g f](std::any const a){if constexpr (std::is_void_vT)g();elseg(std::any_castT const(a));}}; }static std::unordered_mapstd::type_index, std::functionvoid(std::any const)any_visitor {to_any_visitorvoid([]{ std::cout {}; }),to_any_visitorint([](int x){ std::cout x; }),to_any_visitorunsigned([](unsigned x){ std::cout x; }),to_any_visitorfloat([](float x){ std::cout x; }),to_any_visitordouble([](double x){ std::cout x; }),to_any_visitorchar 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());} }templateclass T, class Finline void register_any_visitor(F const f) {std::cout Register visitor for type std::quoted(typeid(T).name()) \n;any_visitor.insert(to_any_visitorT(f)); }auto main() - int {std::vectorstd::any va { {}, 42, 123u, 3.14159f, 2.71828, C17, };std::cout { ;for (const std::any a : va) {process(a);std::cout , ;}std::cout }\n;process(std::any(0xFULL)); // 反注册 y 的类型 unsigned long long std::cout \n;register_any_visitorunsigned long long([](auto x) {std::cout std::hex std::showbase x; });process(std::any(0xFULL)); // OK 0xfstd::cout \n; } 输出:  { {}, 42, 123, 3.14159, 2.71828, C17, } Unregistered type y Register visitor for type y 0xf 6.总结 std::any是一个动态类型变量可以存储任何类型的值。它是由C17引入的一个新特性。std::any的设计目标是提供一种类型安全且易于使用的方式来在运行时处理各种类型的数据因为任何错误的类型转换都会在运行时抛出异常。然而std::any也有一些缺点。首先因为std::any在运行时并不知道它存储的数据的具体类型所以我们需要显式地进行类型转换。这可能会使代码变得复杂和难以理解。其次std::any的性能可能不如其他类型因为它需要在运行时进行类型检查和类型转换。 总之只要掌握了这些std::any的特性明白了它的使用场景才能灵活的使用std::any。 参考std::any - cppreference.com
http://www.zqtcl.cn/news/208878/

相关文章:

  • 廊坊哪里能够做网站网站改版影响
  • 比较好的源码网站手机网站支付如何制作
  • 深圳做网站哪个公司好重庆工程造价信息2021
  • 做电商宠物带哪个网站最好最近一周的重大新闻
  • 做网站难度李沧网站建设电话
  • 六安建设网站网站图片最大尺寸是多少
  • 手机建网站步骤软件优速网站建设
  • 导购网站如何做免费推广用wordpress开发网站模板
  • 建立网站 英语wordpress字体加载
  • 株洲网站建设和制作wordpress 瑞课教育
  • 网站开发培训什么淘宝客网站备案
  • 提供网站制作公司用虚拟机做服务器搭建网站
  • 做煤层气的网站仅对wordpress自带主题有效
  • 优化网站关键词排名东莞网站设计报价
  • 建设厅网站总经济师是干什么的网络运营商电话
  • mvc5 网站开发之美专业企业建站价格
  • 水果电子商务网站建设规划书ipad做网站服务器
  • 网站模版自适应安卓软件开发培训
  • 网络网站建设10大指标开店装修话做那个网站找工人
  • dedecms网站的下载济南网站忧化
  • 深圳北站设计者亚洲国产中文域名查询
  • 有好的学网站建设的书吗龙岗网站建设服务
  • 建个注册页面网站做网站坚持多少年会有起色
  • 做网站是什么职位工商局网站查询入口
  • 做腰椎核磁证网站是 收 七如何做个盈利的网站
  • wordpress查看站点购物网站的后台做哪些东西
  • 文化馆为何需要建设自己的网站网站的建设教程
  • o2o网站策划京北网app下载
  • 公众号链接电影网站怎么做禁止wordpress保存修订版
  • 免费网站建设排行网站开发需要注册账户吗