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

贵州成品网站wordpress 当数据库

贵州成品网站,wordpress 当数据库,嘉兴网,青浦网站制作su35std::array是在C 11标准中增加的STL容器#xff0c;它的设计目的是提供与原生数组类似的功能与性能。也正因此#xff0c;使得std::array有很多与其他容器不同的特殊之处#xff0c;比如#xff1a;std::array的元素是直接存放在实例内部#xff0c;而不是在堆上分配空间它的设计目的是提供与原生数组类似的功能与性能。也正因此使得std::array有很多与其他容器不同的特殊之处比如std::array的元素是直接存放在实例内部而不是在堆上分配空间std::array的大小必须在编译期确定std::array的构造函数、析构函数和赋值操作符都是编译器隐式声明的……这让很s多用惯了std::vector这类容器的程序员不习惯觉得std::array不好用。但实际上std::array的威力很可能被低估了。在这篇文章里我会从各个角度介绍下std::array的用法希望能带来一些启发。本文的代码都在C 17环境下编译运行。当前主流的g 版本已经能支持C 17标准但是很多版本如gcc 7.3的C 17特性不是默认打开的需要手工添加编译选项-stdc 17。自动推导数组大小很多项目中都会有类似这样的全局数组作为配置参数uint32_t g_cfgPara[]  {1, 2, 5, 6, 7, 9, 3, 4};当程序员想要使用std::array替换原生数组时麻烦来了array g_cfgPara  {1, 2, 5, 6, 7, 9, 3, 4};  // 注意模板参数“8”程序员不得不手工写出数组的大小因为它是std::array的模板参数之一。如果这个数组很长或者经常增删成员对数组大小的维护工作恐怕不是那么愉快的。有人要抱怨了std::array的声明用起来还没有原生数组方便选它干啥但是这个抱怨只该限于C 17之前 C 17带来了类模板参数推导特性 你不再需要手工指定类模板的参数array g_cfgPara  {1, 2, 5, 6, 7, 9, 3, 4};  // 数组大小与成员类型自动推导看起来很美好但很快就会有人发现不对头数组元素的类型是什么还是std::uint32_t吗有人开始尝试只提供元素类型参数让编译器自动推导长度遗憾的是它不会奏效。array g_cfgPara  {1, 2, 5, 6, 7, 9, 3, 4};  // 编译错误好吧暂时看起来std::array是不能像原生数组那样声明。下面我们来解决这个问题。用函数返回std::array问题的解决思路是用函数模板来替代类模板——因为C 允许函数模板的部分参数自动推导——我们可以联想到std::make_pair、std::make_tuple这类辅助函数。巧的是 C 标准真的在TS v2试验版本中推出过std::make_array 然而因为类模板参数推导的问世这个工具函数后来被删掉了。但显然用户的需求还是存在的。于是在C 20中 又新增了一个辅助函数std::to_array。别被C 20给吓到了这个函数的代码其实很简单我们可以把它拿过来定义在自己的C 17代码中[1]。templatetypename R, typename P, size_t N, size_t... Iconstexpr array to_array_impl(P (a)[N], std::index_sequence) noexcept{    return { {a[I]...} };} templatetypename T, size_t Nconstexpr auto to_array(T (a)[N]) noexcept{    return to_array_implstd::remove_cv_t, T, N(a, std::make_index_sequence{});} templatetypename R, typename P, size_t N, size_t... Iconstexpr array to_array_impl(P (a)[N], std::index_sequence) noexcept{    return { {move(a[I])...} };} templatetypename T, size_t Nconstexpr auto to_array(T (a)[N]) noexcept{    return to_array_implstd::remove_cv_t, T, N(move(a), std::make_index_sequence{});}细心的朋友会注意到上面这个定义与C 20的推荐实现有所差异这是有目的的。稍后我会解释这么干的原因。现在让我们尝试下用新方法解决老问题auto g_cfgPara  to_array({1, 2, 5, 6, 7, 9, 3, 4});  // 类型不是uint32_t不对啊为什么元素类型不是原来的std::uint32_t这是因为模板参数推导对std::initializer_list的元素拒绝隐式转换如果你把to_array的模板参数从int改为uint32_t会得到如下编译错误D:\Work\Source_Codes\MyProgram\VSCode\main.cpp:51:61: error: no matching function for call to to_array(brace-enclosed initializer list) auto g_cfgPara  to_array({1, 2, 5, 6, 7, 9, 3, 4});D:\Work\Source_Codes\MyProgram\VSCode\main.cpp:34:16: note: candidate: templateclass T, long long unsigned int N constexpr auto to_array(T ()[N]) constexpr auto to_array(T (a)[N]) noexcept                ^~~~~~~~D:\Work\Source_Codes\MyProgram\VSCode\main.cpp:34:16: note:   template argument deduction/substitution failed:D:\Work\Source_Codes\MyProgram\VSCode\main.cpp:51:61: note:   mismatched types unsigned int and int auto g_cfgPara  to_array({1, 2, 5, 6, 7, 9, 3, 4});D:\Work\Source_Codes\MyProgram\VSCode\main.cpp:46:16: note: candidate: templateclass T, long long unsigned int N constexpr auto to_array(T ()[N]) constexpr auto to_array(T (a)[N]) noexcept                ^~~~~~~~D:\Work\Source_Codes\MyProgram\VSCode\main.cpp:46:16: note:   template argument deduction/substitution failed:D:\Work\Source_Codes\MyProgram\VSCode\main.cpp:51:61: note:   mismatched types unsigned int and intHoho有点惨是不绕了一圈回到原点还是不能强制指定类型。这个时候之前针对std::array做的修改派上用场了我给to_array_impl增加了一个模板参数让输入数组的元素和返回std::array的元素用不同的类型参数表示这样就给类型转换带来了可能。为了实现转换到指定的类型我们还需要添加两个工具函数templatetypename R, typename P, size_t Nconstexpr auto to_typed_array(P (a)[N]) noexcept{    return to_array_impl(a, std::make_index_sequence{});} templatetypename R, typename P, size_t Nconstexpr auto to_typed_array(P (a)[N]) noexcept{    return to_array_impl(move(a), std::make_index_sequence{});}这两个函数和to_array的区别是它带有3个模板参数第一个是要返回的std::array的元素类型后两个和to_array一样。这样我们就可以通过指定第一个参数来实现定制std::array元素类型了。auto g_cfgPara  to_typed_array({1, 2, 5, 6, 7, 9, 3, 4});  // 自动把元素转换成uint32_t这段代码可以编译通过和运行但是却有类型转换的编译告警。当然如果你胆子够大可以在to_array_impl函数中放一个static_cast来消除告警。但是编译告警提示了我们一个不能忽视的问题如果万一输入的数值溢出了怎么办auto g_a  to_typed_array({256, -1});  // 数字超出uint8_t范围编译器还是一样的会让你编译通过和运行g_a中的两个元素的值将分别为0和255。如果你不明白为什么这两个值和入参不一样你该复习下整型溢出与回绕的知识了。显然这个方案还不完美。但我们可以继续改进。编译期字面量数值合法性校验首先能想到的做法是在to_array_impl函数中放入一个if判断之类的语句对于超出目标数值范围的输入抛出异常或者做其他处理。这当然可行但要注意的是这些工具函数是可以在运行期调用的对于这种常用的基础函数来说性能至关重要。一旦在里面加入了错误判断意味着运行时的每一次调用性能都会下降。理想的设计是只有在编译期生成的数组才进行校验并且报编译错误。但运行时调用函数时不要加入任何校验。可惜的是至少在C 20之前没有办法指定函数只允许在编译期执行[2]。那有没有其他手段呢熟悉C 的人知道C 的编译期处理大多可以用模板的trick来完成——因为模板参数一定是编译期常量。因此我们可以用模板参数来完成编译期处理——只要把数组元素全部作为模板的非类型参数就可以了。当然这里有个问题模板的非类型参数的类型怎么确定正好C 17提供了auto模板参数的功能可以派上用场templatetypename Tconstexpr void CheckIntRanges() noexcept {}  // 用于终结递归 templatetypename T, auto M, auto... Nconstexpr void CheckIntRanges() noexcept
http://www.zqtcl.cn/news/509103/

相关文章:

  • 电子商务网站设计成功的要素青岛网页设计师
  • 门户网站平台建设方案网站开发后如何上线
  • 濮阳做网站的番禺区网络推广渠道
  • 杭州网站seo外包外链图片
  • 苏州网站建设有限公司枣阳建网站
  • 网站开发平台选择如何制作购物网站
  • 专业建设网站企业外包公司企业网站
  • 网站开发需求确认书国家商标注册官网查询系统
  • 国内个人网站建设wordpress 添加搜索
  • 网站建设创新简述网站开发具体流程
  • wordpress小说网站模板南宁企业网站seo
  • 网站开发与设计课程时间网站推广的搜索引擎推广
  • 网站首页幻灯片不显示网页设计制作项目
  • 遂宁网站建设哪家好深圳做响应式网站设计
  • 慈溪建设企业网站wordpress 增加分类字段
  • 毕业设计做系统网站wordpress修改评论框
  • 上海网站开发孵化设计者联盟官网
  • 旅游网站开发需求报告微信创建小程序
  • 不收费推广网站有哪些h5网站要多久
  • seo网站营销推广全...互联网创业好项目
  • vx小程序制作网站优化标题怎么做
  • 做旅游网站课程设计报告湘潭学校网站建设 x磐石网络
  • 接网站 建设没有网站可以做seo排名吗
  • 抚顺网站seo建设网站需要支付什么插件费用吗
  • 东台做淘宝网站电子商务是学什么
  • 建一个购物网站多少钱wordpress托管在哪里
  • 怎么建设免费网站北京最大的火车站
  • 做视频网站被判刑豫建设标 网站
  • 济南网站建设济南wordpress计次查询
  • 做英文小工具网站赚钱商城网站是免费开吗