ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

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

2026/9/5 15:00:44 拓冰建站 浏览量
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 << "open\n";break;case State::done:std::cout << "done\n";break;case State::progress:std::cout << "progress\n";break;default:assert(nullptr);}
}

// Since C++20
void 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_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); // Warningint n = f(1); // OKreinterpret_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_viewstd::cout << u8'c' << '\n'; // OK in C++17, error in C++20
std::cout << u8"Hello World\n"; // OK in C++17, error in C++20
std::cout << u8"Hello World\n"s; // OK in C++17, error in C++20
std::cout << u8"Hello World\n"sv; // OK in C++17, error in C++20std::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

文章转载自:ChebyshevTST

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