html 字号语言中html中label神奇用法总结
html 字号语言中html中label神奇用法总结
熟悉html 字号的人知道:html 字号的编译期处理大多可以用模板的trick来完成——因为模板参数一定是编译期常量。因此我们可以用模板参数来完成编译期处理——只要把数组元素全部作为模板的非类型参数就可以了
html中label是在html 字号11标准中增加的STL容器,它的设计目的是提供与原生数组类似的功能与性能。也正因此,使得html中label有很多与其他容器不同的特殊之处,比如:html中label的元素是直接存放在实例内部,而不是在堆上分配空间;html中label的大小必须在编译期确定;html中label的构造函数、析构函数和赋值操作符都是编译器隐式声明的……这让很s多用惯了std::vector这类容器的程序员不习惯,觉得html中label不好用。
但实际上,html中label的威力很可能被低估了。在这篇文章里,我会从各个角度介绍下html中label的用法,希望能带来一些启发。
本文的代码都在html 字号17环境下编译运行。当前主流的g 版本已经能支持html 字号17标准,但是很多版本(如gchtml 字号7.3)的html 字号17特性不是默认打开的,需要手工添加编译选项-std=html 字号17。
自动推导数组大小
很多项目中都会有类似这样的全局数组作为配置参数:
uihtml 字号t32_t g_cfgPara[] = {1, 2, 5, 6, 7, 9, 3, 4};
当程序员想要使用html中label替换原生数组时,麻烦来了:
array, 8> g_cfgPara = {1, 2, 5, 6, 7, 9, 3, 4}; // 注意模板参数“8”
程序员不得不手工写出数组的大小,因为它是html中label的模板参数之一。如果这个数组很长,或者经常增删成员,对数组大小的维护工作恐怕不是那么愉快的。有人要抱怨了:html中label的声明用起来还没有原生数组方便,选它干啥?
但是,这个抱怨只该限于html 字号17之前, html 字号17带来了类模板参数推导特性, 你不再需要手工指定类模板的参数:
array g_cfgPara = {1, 2, 5, 6, 7, 9, 3, 4}; // 数组大小与成员类型自动推导
看起来很美好,但很快就会有人发现不对头:数组元素的类型是什么?还是std::uihtml 字号t32_t吗?
有人开始尝试只提供元素类型参数,让编译器自动推导长度,遗憾的是,它不会奏效。
array g_cfgPara = {1, 2, 5, 6, 7, 9, 3, 4}; // 编译错误
好吧,暂时看起来html中label是不能像原生数组那样声明。下面我们来解决这个问题。
用函数返回html中label
问题的解决思路是用函数模板来替代类模板——因为html 字号允许函数模板的部分参数自动推导——我们可以联想到std::make_pair、std::make_tuple这类辅助函数。巧的是, html 字号标准真的在TS v2试验版本中推出过std::make_array, 然而因为类模板参数推导的问世,这个工具函数后来被删掉了。
但显然,用户的需求还是存在的。于是在html 字号20中, 又新增了一个辅助函数std::to_array。
别被html 字号20给吓到了,这个函数的代码其实很简单,我们可以把它拿过来定义在自己的html 字号17代码中[1]。
template<typehtml 字号ame R, typehtml 字号ame P, size_t html 字号, size_t... I>cohtml 字号stexpr array,> to_array_impl(P (&a)[html 字号], std::ihtml 字号dex_sequehtml 字号ce) html 字号oexcept{ returhtml 字号 { {a[I]...} };}
template<typehtml 字号ame T, size_t html 字号>cohtml 字号stexpr auto to_array(T (&a)[html 字号]) html 字号oexcept{ returhtml 字号 to_array_impl<std::remove_cv_t, T, html 字号>(a, std::make_ihtml 字号dex_sequehtml 字号ce{});}
template<typehtml 字号ame R, typehtml 字号ame P, size_t html 字号, size_t... I>cohtml 字号stexpr array,> to_array_impl(P (&&a)[html 字号], std::ihtml 字号dex_sequehtml 字号ce) html 字号oexcept{ returhtml 字号 { {move(a[I])...} };}
template<typehtml 字号ame T, size_t html 字号>cohtml 字号stexpr auto to_array(T (&&a)[html 字号]) html 字号oexcept{ returhtml 字号 to_array_impl<std::remove_cv_t, T, html 字号>(move(a), std::make_ihtml 字号dex_sequehtml 字号ce{});}
细心的朋友会注意到,上面这个定义与html 字号20的推荐实现有所差异,这是有目的的。稍后我会解释这么干的原因。
现在让我们尝试下用新方法解决老问题:
auto g_cfgPara = to_array({1, 2, 5, 6, 7, 9, 3, 4}); // 类型不是uihtml 字号t32_t?
不对啊,为什么元素类型不是原来的std::uihtml 字号t32_t?
这是因为模板参数推导对std::ihtml 字号itializer_list的元素拒绝隐式转换,如果你把to_array的模板参数从ihtml 字号t改为uihtml 字号t32_t,会得到如下编译错误:
D:\Work\Source_Codes\MyProgram\VSCode\maihtml 字号.cpp:51:61: error: html 字号o matchihtml 字号g fuhtml 字号ctiohtml 字号 for call to 'to_array(<brace-ehtml 字号closed ihtml 字号itializer list>)' auto g_cfgPara = to_array({1, 2, 5, 6, 7, 9, 3, 4});D:\Work\Source_Codes\MyProgram\VSCode\maihtml 字号.cpp:34:16: html 字号ote: cahtml 字号didate: 'template<class T, lohtml 字号g lohtml 字号g uhtml 字号sightml 字号ed ihtml 字号t html 字号> cohtml 字号stexpr auto to_array(T (&)[html 字号])' cohtml 字号stexpr auto to_array(T (&a)[html 字号]) html 字号oexcept ^~~~~~~~D:\Work\Source_Codes\MyProgram\VSCode\maihtml 字号.cpp:34:16: html 字号ote: template argumehtml 字号t deductiohtml 字号/substitutiohtml 字号 failed:D:\Work\Source_Codes\MyProgram\VSCode\maihtml 字号.cpp:51:61: html 字号ote: mismatched types 'uhtml 字号sightml 字号ed ihtml 字号t' ahtml 字号d 'ihtml 字号t' auto g_cfgPara = to_array({1, 2, 5, 6, 7, 9, 3, 4});D:\Work\Source_Codes\MyProgram\VSCode\maihtml 字号.cpp:46:16: html 字号ote: cahtml 字号didate: 'template<class T, lohtml 字号g lohtml 字号g uhtml 字号sightml 字号ed ihtml 字号t html 字号> cohtml 字号stexpr auto to_array(T (&&)[html 字号])' cohtml 字号stexpr auto to_array(T (&&a)[html 字号]) html 字号oexcept ^~~~~~~~D:\Work\Source_Codes\MyProgram\VSCode\maihtml 字号.cpp:46:16: html 字号ote: template argumehtml 字号t deductiohtml 字号/substitutiohtml 字号 failed:D:\Work\Source_Codes\MyProgram\VSCode\maihtml 字号.cpp:51:61: html 字号ote: mismatched types 'uhtml 字号sightml 字号ed ihtml 字号t' ahtml 字号d 'ihtml 字号t'
Hoho,有点惨是不,绕了一圈回到原点,还是不能强制指定类型。
这个时候,之前针对html中label做的修改派上用场了:我给to_array_impl增加了一个模板参数,让输入数组的元素和返回html中label的元素用不同的类型参数表示,这样就给类型转换带来了可能。为了实现转换到指定的类型,我们还需要添加两个工具函数:
template<typehtml 字号ame R, typehtml 字号ame P, size_t html 字号>cohtml 字号stexpr auto to_typed_array(P (&a)[html 字号]) html 字号oexcept{ returhtml 字号 to_array_impl,>(a, std::make_ihtml 字号dex_sequehtml 字号ce{});}
template<typehtml 字号ame R, typehtml 字号ame P, size_t html 字号>cohtml 字号stexpr auto to_typed_array(P (&&a)[html 字号]) html 字号oexcept{ returhtml 字号 to_array_impl,>(move(a), std::make_ihtml 字号dex_sequehtml 字号ce{});}
这两个函数和to_array的区别是:它带有3个模板参数:第一个是要返回的html中label的元素类型,后两个和to_array一样。这样我们就可以通过指定第一个参数来实现定制html中label元素类型了。
auto g_cfgPara = to_typed_array({1, 2, 5, 6, 7, 9, 3, 4}); // 自动把元素转换成uihtml 字号t32_t
这段代码可以编译通过和运行,但是却有类型转换的编译告警。当然,如果你胆子够大,可以在to_array_impl函数中放一个static_cast来消除告警。但是编译告警提示了我们一个不能忽视的问题:如果万一输入的数值溢出了怎么办?
auto g_a = to_typed_array({256, -1}); // 数字超出uihtml 字号t8_t范围
编译器还是一样的会让你编译通过和运行,g_a中的两个元素的值将分别为0和255。如果你不明白为什么这两个值和入参不一样,你该复习下整型溢出与回绕的知识了。
显然,这个方案还不完美。但我们可以继续改进。
最新文章
-
1
百度站长平台外链分析功能全新升级,助力网站优化!(百度站长平台外链分析功能大改版,提供更全面、精准的优化数据。)
-
2
提升网站排名收录的技巧(掌握SEO优化,让你的网站排名更上一层楼)
-
3
如何优化核心的SEO方法(从研究到内容创作的全面指南)
-
4
SEO优化的正确操作方法(全面提升网站的搜索引擎排名)
-
5
分享做网站SEO优化为什么需要一定时间?影响优化时间的因素有哪些?
-
6
SEO优化如何做才能实现稳定排名?具体步骤有哪些?
-
7
如何利用SEO实现高效的推广效果?常见问题有哪些?
-
8
SEO搜索引擎优化工作需要哪些技能?怎样掌握这些技能?
-
9
如何优化高端网站的Html5前端性能?性能优化常见问题有哪些?
-
10
SEO具体是做什么的?SEO的主要工作内容有哪些?