C++20语言核心特性的变化

using for Enumeration Values

  对比一下C++20前后的区别:

enum class State {     open,     progress,     done = 9 }; // Before C++20 void print(State s) {     switch (s) {         case State::open:             std::cout << "openn";             break;         case State::done:             std::cout << "donen";             break;         case State::progress:             std::cout << "progressn";             break;         default:             assert(nullptr);     } }
// Since C++20 void print1(State s) {     using enum State;     switch (s) {         case open:             std::cout << "openn";             break;         case done:             std::cout << "donen";             break;         case progress:             std::cout << "progressn";             break;         default:             assert(nullptr);     } }  void print2(State s) {     using State::open, State::done, State::progress;     switch (s) {         case open:             std::cout << "openn";             break;         case done:             std::cout << "donen";             break;         case progress:             std::cout << "progressn";             break;         default:             assert(nullptr);     } }

 

Range-Based for Loop with Initialization

  基于范围的for循环是C++11引入的新特性,自C++20起,基于范围循环也可以进行初始化。

int main() {     std::vector v{1, 2, 3};     for (int i{1}; const auto& item : v)         std::cout << std::format("{}: {}n", i++, item); }

 

Feature Test Macros

  特性测试宏,正如其名,是为了当前版本编译器是否支持某个语言特性。这个宏以__cpp为前缀。

#if __cpp_generic_lambdas >= 201707     // generic lambdas with template parameters can be used #endif  #ifndef __cpp_lib_as_const template <typename T> const T& as_const(T& t) {     return t; } #endif

 

Attribute [[no_unique_address]]

#include <iostream>  struct Empty {};  struct I {     int i; };  struct S {     Empty e;     int i; };  int main() {     std::cout << "sizeof(Empty): " << sizeof(Empty) << 'n';     std::cout << "sizeof(I): " << sizeof(I) << 'n';     std::cout << "sizeof(S): " << sizeof(S) << 'n'; }

  空类为了区分不同对象的地址,字节大小是1;而结构体S由于内存对齐的原因,所以字节大小是8。输出结果毫无疑问是1,4,8。

#include <iostream>  struct Empty {};  // EBCO struct S : Empty {     int i; };  // no_unique_address struct S2 {     [[no_unique_address]] Empty e;     int i; };  int main() {     std::cout << "sizeof(Empty): " << sizeof(Empty) << 'n';     std::cout << "sizeof(S): " << sizeof(S) << 'n';     std::cout << "sizeof(S2): " << sizeof(S2) << 'n'; }

  注解标签no_unique_address能起到和空基类优化相同的效果。

 

Attributes [[likely]] and [[unlikely]]

  在if/else,switch分支当中都可以使用,帮助编译器作分支预测的优化。

int f(int n) {     if (n <= 0) [[unlikely]] {         return n;     } else {         return n * n;     } }  int g(int n) {     if (n <= 0) {         return n;     } else [[likely]] {         return n * n;     } }  int h(int n) {     switch (n) {         case 1:             //             break;         [[likely]] case 2:             //              break;     }      return 0; }

 

Attribute [[nodiscard]] with Parameter

  nodiscard用于修饰函数,当被修饰的函数发生调用(仅仅调用而不作赋值或者强制转换操作),编译器会报警告信息。

[[nodiscard]] int f(int n) {     return n; }  int main() {     f(1); // Warning     int n = f(1); // OK     reinterpret_cast<int *>(f(1)); // OK }

 

New Character Type char8_t

    using namespace std::literals;      auto c = u8'c'; // char8_t     auto s = u8"Hello World"; // const char8_t *     auto str1 = u8"Hello World"s; // std::u8string     auto str2 = u8"Hello World"sv; // std::u8string_view      std::cout << u8'c' << 'n'; // OK in C++17, error in C++20     std::cout << u8"Hello Worldn"; // OK in C++17, error in C++20     std::cout << u8"Hello Worldn"s; // OK in C++17, error in C++20     std::cout << u8"Hello Worldn"sv; // OK in C++17, error in C++20      std::cout << c << 'n'; // OK in C++17, error in C++20     std::cout << s << 'n'; // OK in C++ 17, error in C++20     std::cout << str1 << 'n'; // OK in C++17, error in C++20     std::cout << str2 << 'n'; // OK in C++17, error in C++20

  更多的介绍将在下次带来,感谢支持😃

发表评论

评论已关闭。

相关文章