跟我学c++中级篇——c++17之constexprif-创新互联

一、constexpr

在前文对const的几种形式进行了分析说明,但是constexpr if的应用没有顾及到。在模板元编程constexpr可以起到一种类似于if else的作用。毕竟不管在哪里运行,哪个时期运行,条件判断总是需要的。在早期的模板编程中,如果想做这种判断需要使用常见的如enable_if之类的模板,特别是c++的灵活性会产生一些代码,它不符合c++的规范(即不推荐这么写),但又被编译使用(c++又支持),这种情况被称做ill-formed
,如果是类型则ill-formed type,cppreference称之为非良构类型。
这就又回到前面提到的SFINAE和Concepts,而在模板板的元编程里这又一是种强需求,所以以这条线来看c++标准的迭代,就会看到,对类似的支持是越来越完善。明白了这些,再回头学习和应用constexpr if就会有的放矢,知其然,并知其所以然。

创新互联是一家专注于成都网站制作、成都做网站与策划设计,孟津网站建设哪家好?创新互联做网站,专注于网站建设十多年,网设计领域的专业建站公司;建站业务涵盖:孟津等地区。孟津做网站价格咨询:18980820575二、constexpr if

先看一个例子,来理解constexpr if:

//C++17以前
templatestd::enable_if_t::value, std::string>to_string(T t){
   return std::to_string(t);
 }
 ​
templatestd::enable_if_t::value, std::string>to_string(T t){
   return t;
 }
//c++17以后
templateauto to_string(T t) {
   if constexpr(std::is_integral::value) {
     return std::to_string(t);
   } else {
     return t;
   }
 }

一般来说,在模板中进行分支控制主要有以下几种情况,一个是采用偏特化机制,对不同的类型参数输入产生不同的结果,这个在前面的false_type中就有体现;另外一个是使用std::enable_if_t来实现;然后就是今天分析的constexpr if。在编译器控制分支的情况下,在c++17以前,无论哪种分支,都是会被编译的,但是在c++17后,不会控制到的则不会编译,不过虽然如此,另外的分支仍然要符合c++的语法,否则仍然是无法编译通过。
上面这个例子把偏特化的例子省略了,其实从模板元编程的角度看,就是对SFINAE技术的一个优化和简化的过程。把这些基本的情况了解后,回头再看constexpr if就会有一个比较深刻的理解。
然后来分析一下它的定义:constexpr if是一种在编译期进行分支控制的写法,constexpr可以紧跟在if的后面。通过对条件块中不满足的部分直接处理掉,但是这有一个前提,这个条件块必须是一个常量表达式并且可以显示的转换成布尔值。

三、应用

前面提到过constexptr if主要是对模板元编程的支持,它能够起到让代码更直观,更简便,使得在编译期内的元编程不再像SFINAE那样晦涩。下面再看一个数列的计算:

#pragma once
templateconstexpr long Fib() {
    if constexpr (N >= 2) {
        return Fib() + Fib();
    }
    else {
        return N;
    }
}

void TestFib() {
    static_assert(Fib<0>() == 0);
    static_assert(Fib<1>() == 1);
    static_assert(Fib<2>() == 1);
    static_assert(Fib<3>() == 2);
}
int main()
{
    TestFib();
    return 0;
}

这个例子没有判断值的范围,但是这里重点是讲constexpr if的用法,所以不必太再乎这个。是不是非常简单,它和印象中在执行期运行的代码已经长得很像了。
使用constexpr if优点不少,它可以减少代码的编译生成数量,也可以更简洁是了,但它也不少的受限情况:比如函数和运行期类似,在某些情况下没有写constexpr仍然可以运行,而这种运行则无法在编译期优化了。同时,其多多类型返回无能为力。所以在实际应用中,还是要小心为妙。
总体来看,constexpr if的应用场景还是很受限的,它只能放在一般意义的函数内部,如果必须需要减小编译出的代码文件的大小,尽量减少依赖资源,它还是有可能施展身手的。更具体的情况需要开发者根据需要来确定它的应用。

四、总结

constexpr的详细用法不同版本都在网上有详细的说明,但如何能更好的在何处使用它,这才是一个比较让人头疼的问题。正如上学一样,老师一讲就明白,自己做题就糊涂。如何打破这个怪圈,就需要从基础入手,反复把基础的知识吃透,然后再结合例程自己不断修改完善,才有机会冲出桎梏,解放思想。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


名称栏目:跟我学c++中级篇——c++17之constexprif-创新互联
网站地址:http://lszwz.com/article/dhjsgo.html

其他资讯

售后响应及时

7×24小时客服热线

数据备份

更安全、更高效、更稳定

价格公道精准

项目经理精准报价不弄虚作假

合作无风险

重合同讲信誉,无效全额退款