跟我学c++中级篇——c++17之constexpr if

一、constexpr

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

二、constexpr if

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

//C++17以前
template <typename T>
std::enable_if_t<std::is_integral<T>::value, std::string>
 to_string(T t){
   return std::to_string(t);
 }
 ​
template <typename T>
std::enable_if_t<!std::is_integral<T>::value, std::string>
 to_string(T t){
   return t;
 }
//c++17以后
template <typename T>
auto to_string(T t) {
   if constexpr(std::is_integral<T>::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
template<long N>
constexpr long Fib() {
    if constexpr (N >= 2) {
        return Fib<N - 1>() + Fib<N - 2>();
    }
    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的详细用法不同版本都在网上有详细的说明,但如何能更好的在何处使用它,这才是一个比较让人头疼的问题。正如上学一样,老师一讲就明白,自己做题就糊涂。如何打破这个怪圈,就需要从基础入手,反复把基础的知识吃透,然后再结合例程自己不断修改完善,才有机会冲出桎梏,解放思想。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
If you’ve ever asked “what’s in C++17 and what does it mean for me and my code?” — and I hope you have — then this book is for you. Now that the C++ standard is being released regularly every three years, one of the challenges we have as a community is learning and absorbing the new features that are being regularly added to the standard language and library. That means not only knowing what those features are, but also how to use them effectively to solve problems. Bartlomiej Filipek does a great job of this by not just listing the features, but explaining each of them with examples, including a whole Part 3 of the book about how to apply key new C++17 features to modernize and improve existing code — everything from upgrading enable_if to the new if constexpr, to refactoring code by applying the new optional and variant vocabulary types, to writing parallel code using the new standard parallel algorithms. In each case, the result is cleaner code that’s often also significantly faster too. The point of new features isn’t just to know about them for their own sake, but to know about how they can let us express our intent more clearly and directly than ever in our C++ code. That ability to directly “say what we mean” to express our intent, or to express “what” we want to achieve rather than sometimes-tortuous details of “how” to achieve it through indirect mechanisms, is the primary thing that determines how clean and writable and readable — and correct — our code will be. For C++ programmers working on real-world projects using reasonably up-to-date C++ compilers, C++17 is where it’s at in the industry today for writing robust production code. Knowing what’s in C++17 and how to use it well is an important tool that will elevate your day-to-day coding, and more likely than not reduce your day-to-day maintenance and debugging chores. If you’re one of the many who have enjoyed Barteks’s blog (bfilipek.com, frequently cited at isocpp.org), you’ll certainly also enjoy this entertaining and informative book. And if you haven’t enjoyed his blog yet, you should check it out too… and then enjoy the book.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值