详解C++17中if和switch语句的新特性

 更新时间:2023年12月17日 09:56:56   作者:fengbingchun  
这篇文章主要为大家详细介绍了C++17中if和switch语句的新特性的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

1.从C++17开始,if语句允许在条件表达式里添加一条初始化语句。当仅在if语句范围内需要变量时,使用这种形式的if语句。在if语句的条件表达式里定义的变量将在整个if语句中有效,包括else部分。

std::mutex mx;
bool shared_flag = true; // guarded by mx
constexpr int get_value() { return 66; }
 
int test_if_init()
{
    std::map<std::string, std::string> addrs{
        {"csdn", "https://blog.csdn.net/fengbingchun/"},
        {"github", "https://github.com/fengbingchun"}
    };
 
    if (auto it = addrs.find("github"); it != addrs.end())
        std::cout << "github:" << it->second << "\n"; // github:https://github.com/fengbingchun
 
    if (auto it = addrs.find("csdn"); it == addrs.end())
        std::cout << "no find\n";
    else // if中的it变量在else分支中也有效
        std::cout << "csdn:" << it->second << "\n"; // csdn:https://blog.csdn.net/fengbingchun/
 
    if (auto [it, inserted] = addrs.insert({ "gitee", "https://gitee.com/fengbingchun/test.git" }); !inserted)
        std::cout << "already exists\n";
    else
        std::cout << "inserted successfully: key:" << it->first << ", value:" << it->second << "\n"; // inserted successfully: key:gitee, value:https://gitee.com/fengbingchun/test.git
 
    if (auto x = get_value(); x == 66)
        std::cout << "x is:" << x << "\n"; // x is:66
 
    if (std::lock_guard<std::mutex> lock(mx); shared_flag) {
        std::cout << "setting shared_flag to false\n"; // setting shared_flag to false
        shared_flag = false;
    }
 
    if (auto val1 = addrs.cbegin()->first, val2 = addrs.crbegin()->first; val1 != val2)
        std::cout << "val1:" << val1 << ", val2:" << val2 << "\n"; // val1:csdn, val2:github
 
    const std::string str{ "if" };
    if (auto keywords = { "if", "for", "while" }; std::any_of(keywords.begin(), keywords.end(), [&str](const char* kw) { return str == kw; }))
        std::cout << "Error:Token must not be a keyword\n"; // Error:Token must not be a keyword
 
    return 0;
}

2.从C++17开始,switch语句允许在条件表达式里添加一条初始化语句,其范围仅限于switch语句块。通过使用带初始化的switch语句,我们可以在对条件表达式求值之前初始化一个对象/实体,用法与以上的if相同。

int test_switch_init()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_int_distribution<int> dist(0, 100);
 
    switch (auto val = dist(mt); val) {
        default:
            std::cout << "val:" << val << "\n"; // val:20
    }
    
    return 0;
}

3.从C++17开始,你可以在函数模版中使用if constexpr语句做出编译时分支决策,而无需使用(resort)多个函数重载.

if constexpr语句在编译时求值,编译器仅生成与发送到函数模板的参数类型相匹配的if分支的代码。该功能主要用在模版中,它允许仅编译特定的语句,具体取决于模版类型。

注意:

(1).if constexpr和if的唯一区别是:if constexpr在编译时进行判断,而if在运行时进行判断;所以,使用if constexpr的代码在编译完成后,程序的这一部分其实就不会有分支存在。

(2).通过使用语法if constexpr,编译器可以计算编译期的条件表达式,在编译期决定使用哪部分,其余部分的代码将会被丢弃,但会进行语法检查。所有的static_assert也必须有效,即使所在的分支没有被编译。

(3).不能在函数体之外使用if constexpr.

(4).if constexpr不支持短路求值(当&&左侧为false时停止求值,当||左侧为true时停止求值)。

(5).if constexpr可以在任何函数中使用,而并非仅限于模版。只要条件表达式是编译期的,并且可以转换成bool类型。

(6).在泛型代码之外使用if constexpr的唯一好处是被丢弃的部分不会成为最终程序的一部分,这将减小生成的可执行程序的大小。

template<typename T>
auto show(T t)
{
    //if (std::is_pointer_v<T>) // show(a) results in compiler error for return *t. show(p) results in compiler error for return t.
    if constexpr (std::is_pointer_v<T>) // this statement goes away for show(a)
        return *t;
    else
        return t;
}
 
template<typename T>
void print_value(const T& value)
{
    if constexpr (std::is_same_v<T, std::string>)
        std::cout << "type: std::string: value: " << value << ", length: " << value.length() << "\n";
    else if constexpr (std::is_same_v<T, int>)
        std::cout << "type: int: value: " << value << "\n";
    else if constexpr (std::is_same_v<T, float>)
        std::cout << "type: float: value: " << value << "\n";
    else
        std::cout << "unsupported type\n";
}
int test_if_constexpr()
{
    int a = 66;
    int* p = &a;
    std::cout << show(a) << "\n"; // 66
    std::cout << show(p) << "\n"; // 66
    std::string str{ "hello" };
    print_value(str); // type: std::string: value: hello, length: 5
    print_value(a); // type: int: value: 66
    float val{.6f };
    print_value(val); // type: float: value: 0.6
    print_value(p); // unsupported type
    return 0;
}

执行结果如下图所示:

GitHubhttps://github.com/fengbingchun/Messy_Test

到此这篇关于详解C++17中if和switch语句的新特性的文章就介绍到这了,更多相关C++17 if switch内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++循环链表之约瑟夫环的实现方法

    C++循环链表之约瑟夫环的实现方法

    这篇文章主要介绍了C++循环链表之约瑟夫环的实现方法,对于学习数据结构与算法有一定的借鉴价值,需要的朋友可以参考下
    2014-09-09
  • C++单一职责原则示例代码浅析

    C++单一职责原则示例代码浅析

    我们在设计一个类时要学会发现职责,并把那些职责相互分离,其实要去判断是否应该分离出一个类来并不难,前面说过,一个类应该只有一个引起它变化的原因,如果你能想到其它的原因也能去改变这个类,那么这个类就具有多于1个的职责,就应该考虑类的职责分离
    2023-02-02
  • vc中使用SendMessage自定义消息函数

    vc中使用SendMessage自定义消息函数

    这篇文章主要介绍了vc中使用SendMessage自定义消息函数的相关资料,需要的朋友可以参考下
    2015-06-06
  • Java C++ 算法题解拓展leetcode670最大交换示例

    Java C++ 算法题解拓展leetcode670最大交换示例

    这篇文章主要介绍了Java C++算法题解拓展leetcode670最大交换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • C语言进阶教程之字符串&内存函数

    C语言进阶教程之字符串&内存函数

    对于字符,在计算机内部都是用数字(字符编码)来表示的,而字符串是“字符连续排列”的一种表现,这篇文章主要给大家介绍了关于C语言进阶教程之字符串&内存函数的相关资料,需要的朋友可以参考下
    2021-09-09
  • C语言实现动态链表的示例代码

    C语言实现动态链表的示例代码

    本文主要介绍了C语言实现动态链表的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • C语言查找数组里数字重复次数的方法

    C语言查找数组里数字重复次数的方法

    这篇文章主要介绍了C语言查找数组里数字重复次数的方法,涉及C语言针对数组的遍历与判断技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • C++实现LeetCode(132.拆分回文串之二)

    C++实现LeetCode(132.拆分回文串之二)

    这篇文章主要介绍了C++实现LeetCode(132.拆分回文串之二),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Protocol Buffer技术深入理解(C++实例)

    Protocol Buffer技术深入理解(C++实例)

    C++实例Protocol Buffer技术详解,感兴趣的朋友可以了解下
    2013-01-01
  • 使用C++一步步实现俄罗斯方块后续

    使用C++一步步实现俄罗斯方块后续

    本文主要给大家分享的是作者在使用C++制作俄罗斯方块小游戏的时候所需要的常用的函数,有需要的小伙伴可以借鉴下,希望大家能够喜欢。
    2017-12-12

最新评论