C 20尝鲜:新增语法糖

指定初始化

现在可以初始化特定(指定的)聚合成员并跳过其他成员。与C语言不同,初始化顺序必须与聚合声明相同。

#include <iostream>#include <string>struct S{ int x; int y{2}; std::string s;}; int main(){ S s1{.y = 3}; // {0, 3, {}} S s2 = {.x = 1, .s = 'abc'}; // {1, 2, {'abc'}} //S s3{.y = 1, .x = 2}; // Error, x should be initialized before y std::cout << s1.y << std::endl; return 0;}

在线测试

https://wandbox.org/nojs/gcc-headhttps://wandbox.org/nojs/clang-head

位域的默认成员初始化器

在C++ 20之前,要为位域提供默认值,必须创建默认构造函数,现在可以使用方便的默认成员初始化语法来实现。

#include <iostream>#include <string>#include <stdio.h>// until C++20:struct S1{ int a : 1; int b : 1; S1() : a{0}, b{1}{}};// since C++20:struct S2{ short int a : 1 {0}; short int b : 1 {1};}; int main(){ S1 s1; S2 s2; std::cout << sizeof(s1) << std::endl; printf( 'S2.b : %hhu\n', s1.b ); std::cout << sizeof(s2) << std::endl; printf( 'S2.b : %hhu\n', s2.b ); return 0;}

typename更多的选项

typename可以在只出现类型名的上下文中省略(类型转换、返回类型、类型别名、成员类型、成员函数的参数类型等)。

嵌套的内联名称空间

inline关键字允许出现在嵌套的命名空间定义中:

#include <iostream>#include <string>#include <stdio.h>// C++20namespace A::B::inline C1{    void f(){std::cout << 'C1' << std::endl;}}// C++17namespace A::B{    inline namespace C2{        void f(){std::cout << 'C2' << std::endl;}    }}int main(){    A::B::C1::f();    A::B::C2::f();    return 0;}

using enum

作用域枚举很棒,唯一的问题是它们的冗长使用(例如my_enum::enum_value)。例如,在检查每个可能的enum值的switch语句中,应该为每个case-label重复my_enum:: part。使用enum声明将所有枚举名称引入当前作用域,因此它们作为非限定名称可见,my_enum::部分可以省略。它可以应用于无作用域枚举,甚至单个枚举器。

#include <iostream>#include <string>#include <stdio.h>namespace my_lib { enum class color { red, green, blue }; enum COLOR {RED, GREEN, BLUE}; enum class side {left, right};}void f(my_lib::color c1, my_lib::COLOR c2){ using enum my_lib::color; // introduce scoped enum using enum my_lib::COLOR; // introduce unscoped enum using my_lib::side::left; // introduce single enumerator id // C++17 if(c1 == my_lib::color::red){std::cout << 'red' << std::endl;} // C++20 if(c1 == green){/*...*/} if(c2 == RED){std::cout << 'RED' << std::endl;} auto r = my_lib::side::right; // qualified id is required for `right` auto l = left; // but not for `left`}int main(){ f(my_lib::color::red, my_lib::COLOR::RED); return 0;}

new 表达式中的数组大小推到

这个修复允许编译器推导new表达式中的数组大小,就像它对局部变量所做的那样。

#include <iostream>#include <string>#include <stdio.h>int main(){    // before C++20    int p0[]{1, 2, 3};    int* p1 = new int[3]{1, 2, 3};  // explicit size is required    // since C++20    int* p2 = new int[]{1, 2, 3};    int* p3 = new int[]{};  // empty    char* p4 = new char[]{'hi'};    // works with parenthesized initialization of aggregates    int p5[](1, 2, 3);    int* p6 = new int[](1, 2, 3);    return 0;}

为别名模板推导类模板参数

#include <iostream>#include <string>#include <stdio.h>template<typename T>using IntPair = std::pair<int, T>;int main(){ double d{}; IntPair<double> p0{1, d}; // C++17 IntPair p1{1, d}; // std::pair<int, double> // C++20 IntPair p2{1, p1}; // std::pair<int, std::pair<int, double>> return 0;}
(0)

相关推荐