C++17中的constexpr

栏目: C++ · 发布时间: 6年前

内容简介: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


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

重构

重构

[美]马丁•福勒(Martin Fowler) / 熊节 / 人民邮电出版社 / 2015-8 / 69.00

本书清晰揭示了重构的过程,解释了重构的原理和最佳实践方式,并给出了何时以及何地应该开始挖掘代码以求改善。书中给出了70 多个可行的重构,每个重构都介绍了一种经过验证的代码变换手法的动机和技术。本书提出的重构准则将帮助你一次一小步地修改你的代码,从而减少了开发过程中的风险。一起来看看 《重构》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具