写点什么

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

作者:EquatorCoco
  • 2023-12-01
    福建
  • 本文字数:2097 字

    阅读完需:约 7 分钟

using for Enumeration Values


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


enum class State {    open,    progress,    done = 9};// Before C++20void print(State s) {    switch (s) {        case State::open:            std::cout << "open\n";            break;        case State::done:            std::cout << "done\n";            break;        case State::progress:            std::cout << "progress\n";            break;        default:            assert(nullptr);    }}
复制代码


// Since C++20void print1(State s) {    using enum State;    switch (s) {        case open:            std::cout << "open\n";            break;        case done:            std::cout << "done\n";            break;        case progress:            std::cout << "progress\n";            break;        default:            assert(nullptr);    }}
void print2(State s) { using State::open, State::done, State::progress; switch (s) { case open: std::cout << "open\n"; break; case done: std::cout << "done\n"; break; case progress: std::cout << "progress\n"; 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_consttemplate <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 {};
// EBCOstruct S : Empty { int i;};
// no_unique_addressstruct 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_tauto s = u8"Hello World"; // const char8_t *auto str1 = u8"Hello World"s; // std::u8stringauto str2 = u8"Hello World"sv; // std::u8string_view
std::cout << u8'c' << '\n'; // OK in C++17, error in C++20std::cout << u8"Hello World\n"; // OK in C++17, error in C++20std::cout << u8"Hello World\n"s; // OK in C++17, error in C++20std::cout << u8"Hello World\n"sv; // OK in C++17, error in C++20
std::cout << c << '\n'; // OK in C++17, error in C++20std::cout << s << '\n'; // OK in C++ 17, error in C++20std::cout << str1 << '\n'; // OK in C++17, error in C++20std::cout << str2 << '\n'; // OK in C++17, error in C++20
复制代码


文章转载自:ChebyshevTST

原文链接:https://www.cnblogs.com/ChebyshevTST/p/17868410.html

用户头像

EquatorCoco

关注

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
C++20语言核心特性的变化_c++_EquatorCoco_InfoQ写作社区