建网站公司哪里好集团公司做网站的好处有什么
建网站公司哪里好,集团公司做网站的好处有什么,做网站报价单,哪些网站专门做细胞的一、模板元编程库
在C的标准库中提供了相关的元编程库#xff0c;提供了一系列的对相关元编程相关的接口#xff0c;极大的方便了开发者在元编程时的工作。在前面也分析过几个元编程的接口#xff0c;今天接着分析一下指针处理的元编程接口std::is_pointer。
二、std::is_po…一、模板元编程库在C的标准库中提供了相关的元编程库提供了一系列的对相关元编程相关的接口极大的方便了开发者在元编程时的工作。在前面也分析过几个元编程的接口今天接着分析一下指针处理的元编程接口std::is_pointer。二、std::is_pointer标准库中对其的定义为templateclass Tstructis_pointer;说明也写得非常清楚它只能检查T是不是一个对象或函数的指针还特别注明了包括void指针但不包括成员指针。它提供了对cv限定符的支持其可能实现的源码如下templateclass Tstructis_pointer:std::false_type{};templateclass Tstructis_pointerT*:std::true_type{};templateclass Tstructis_pointerT*const:std::true_type{};templateclass Tstructis_pointerT*volatile:std::true_type{};templateclass Tstructis_pointerT*constvolatile:std::true_type{};std::true_type这哥俩用到的地方还是挺频繁的。这段代码没啥可解析的在不同的库中实现有些大同小异但基本都差不多。再看一个cppreference的例子#includetype_traitsintmain(){structA{intm;voidf(){}};intA::*mem_data_ptrA::m;// a pointer to member datavoid(A::*mem_fun_ptr)()A::f;// a pointer to member functionstatic_assert(!std::is_pointerA::value!std::is_pointer_vA// same thing as above, but in C17!!std::is_pointerA()// same as above, using inherited operator bool!std::is_pointerA{}// ditto!std::is_pointerA()()// same as above, using inherited operator()!std::is_pointerA{}()// dittostd::is_pointer_vA*std::is_pointer_vAconst*volatile!std::is_pointer_vA!std::is_pointer_vdecltype(mem_data_ptr)!std::is_pointer_vdecltype(mem_fun_ptr)std::is_pointer_vvoid*!std::is_pointer_vintstd::is_pointer_vint*std::is_pointer_vint**!std::is_pointer_vint[10]!std::is_pointer_vstd::nullptr_tstd::is_pointer_vvoid(*)());}是不是觉得代码很easy确实如此。但越是这样越是要小心。三、问题和分析将上面的代码改一下直接传递进去一个多级指针会是什么样呢比如下面这样class Demo{};intmain(){static_assert(std::is_pointerDemo*::value,Demo is not a pointer type);static_assert(std::is_pointerDemo**::value,Demo is not a pointer type);return0;}这种情况顺利的通过了编译。表面上看上去没问题如果只是单纯的处理指针可能觉得也没有什么问题啊。但实际上如果实际的目的操作的是一个“*Demo”时前者可以得到一个Demo的对象而后者只能得到一个Demo的指针这就让后面的行为出现了异化。这对于普通编程来说还好发现但对于模板编程时可能就很难定位问题。这就需要进行预防性的处理。有的开发者可能还没有细看说明把成员内的指针提供给了这个接口应用如下面这样structS{intfoo(){return0;}};intmain(){static_assert(std::is_pointerdecltype(S::foo)::value,S::foo is not a member pointer);//static_assert(std::is_member_pointerdecltype(S::foo)::value, S::foo is not a member pointer);//OKreturn0;}这也是不正确的用法。说明中详细了表示了不支持成员指针的处理。所以在元编程的标准库中还提供了一个std::is_member_pointer用来判断成员的指针属性的情况也算是完善了std::is_pointer不能判断成员指针的情况。四、处理方法那么如何处理is_pointer只能检测最外层指针的情况呢最简单的方法仍然是采用元编程库提供的std::remove_pointer递归判断。毕竟几乎没有人写超过三级指针的情况到二级已经是大多数人的极限了。用大牛的话说不是说不可以用更多级的指针实现但这恰恰说明了设计上的问题。扯远了先看使用std::remove_pointer递归解决二级指针的处理方式#includeiostream#includetype_traitstemplatetypename TvoidcheckPointerLevel(T ptr){ifconstexpr(std::is_pointer_vT){std::coutthis is pointer!;// 递归检查指针级别intlevel0;using curTypeT;// remove_pointer处理并检查using BaseTypestd::remove_pointer_tT;ifconstexpr(std::is_pointer_vBaseType){std::couttwice-level pointer!std::endl;}else{std::coutfirst-level pointer!std::endl;}}else{std::coutnot a pointer!std::endl;}}当然也可以使用SFINAE技术处理#includeiostream#includetype_traits#includevectortemplatetypename TvoidimplCheck(T value,std::true_type){using BaseTypetypename std::remove_pointerT::type;//业务处理}templatetypename TvoidimplCheck(T value,std::false_type){//业务处理}templateclass Uvoidprocess(Ut){implCheck(std::forwardU(t),std::is_pointerstd::remove_reference_tU{});}其实原理都在前面分析过此处不再赘述。代码也不复杂明白几个基础的元编程接口即可。五、总结在应用库或者第三方接口时要认真严格的查看相关的接口说明一定不能想当然的进行利用。本文这个指针处理的元编程接口就很容易让初学者上当。这就需要开发者能够全面细致的掌握应用的细节并在适当的例程中进行测试验证。这样才能更好的在工程实践中写出健壮稳定的代码。