内容简介:C++17中的constexpr
constexpr if
constexpr标记一个表达式或一个函数的返回结果是编译期常量,它保证函数会在编译期执行。相比模版来说,实现编译期循环或递归,C++17中的constexpr if会让代码变得更简洁易懂。比如实现一个编译期整数加法:
template<int N> constexpr int sum() { return N; } template <int N, int N2, int... Ns> constexpr int sum() { return N + sum<N2, Ns...>(); }
C++17之前你可能需要像上面这样写,但是现在你可以写更简洁的代码了
template <int N, int... Ns> constexpr auto sum17() { if constexpr (sizeof...(Ns) == 0) return N; else return N + sum17<Ns...>(); }
当然,你也可以用C++17的fold expression
template<typename ...Args> constexpr int sum(Args... args) { return (0 + ... + args); }
constexpr还可以用来消除enable_if了,对于讨厌写一长串enable_if的人来说会非常开心。比如我需要根据类型来选择函数的时候:
template<typename T> std::enable_if_t<std::is_integral<T>::value, std::string> to_str(T t) { return std::to_string(t); } template<typename T> std::enable_if_t<!std::is_integral<T>::value, std::string> to_str(T t) { return t; }
经常不得不分开几个函数来写,还需要写长长的enable_if,比较繁琐,通过if constexpr可以消除enable_if了。
template<typename T> auto to_str17(T t) { if constexpr(std::is_integral<T>::value) return std::to_string(t); else return t; }
constexpr if让C++的模版具备if-else if-else功能了,是不是很酷,C++程序员的好日子来了:)
不过需要注意的是这种写法是有问题的哦。
template<typename T> auto to_str17(T t) { if constexpr(std::is_integral<T>::value) return std::to_string(t); return t; }
这个代码把else去掉了,当输入如果是非数字类型的时候代码可以编译过,以为if constexpr在模版实例化的时候会丢弃不满足条件的部分,因此函数体中的前两行代码将失效,只有最后一句有效。当输入的为数字的时候就会产生编译错误了,因为if constexpr满足条件了,这时候就会有两个return了,就会导致编译错误。
constexpr if还可以用来替换#ifdef宏,看下面的例子
enum class OS { Linux, Mac, Windows }; //Translate the macros to C++ at a single point in the application #ifdef __linux__ constexpr OS the_os = OS::Linux; #elif __APPLE__ constexpr OS the_os = OS::Mac; #elif __WIN32 constexpr OS the_os = OS::Windows; #endif void do_something() { //do something general if constexpr (the_os == OS::Linux) { //do something Linuxy } else if constexpr (the_os == OS::Mac) { //do something Appley } else if constexpr (the_os == OS::Windows) { //do something Windowsy } //do something general } //备注:这个例子摘自https://blog.tartanllama.xyz/c++/2016/12/12/if-constexpr/
代码变得更清爽了,再也不需要像以前一样写#ifdef那样难看的代码块了。
constexpr lambda
constexpr lambda其实很简单,它的意思就是可以在constexpr 函数中用lambda表达式了,这在C++17之前是不允许的。这样使用constexpr函数和普通函数没多大区别了,使用起来非常舒服。下面是constexpr lambda的例子:
template <typename I> constexpr auto func(I i) { //use a lambda in constexpr context return [i](auto j){ return i + j; }; }
constexpr if和constexpr lambda是C++17提供的非常棒的特性,enjoy it.
Post Views: 6
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Realm of Racket
Matthias Felleisen、Conrad Barski M.D.、David Van Horn、Eight Students Northeastern University of / No Starch Press / 2013-6-25 / USD 39.95
Racket is the noble descendant of Lisp, a programming language renowned for its elegance and power. But while Racket retains the functional goodness of Lisp that makes programming purists drool, it wa......一起来看看 《Realm of Racket》 这本书的介绍吧!