
C++20/17/14/11新特性概览
项目提供C++20/17/14/11新特性概览,涵盖各版本引入的语言和库功 能。包括C++20的协程、概念、指定初始化器,C++17的变体、可选值、文件系统,以及C++14和C++11的主要更新。为开发者提供现代C++新特性的参考资源,便于快速了解语言演进。
C++20 includes the following new language features:
C++20 includes the following new library features:
C++17 includes the following new language features:
C++17 includes the following new library features:
C++14 includes the following new language features:
C++14 includes the following new library features:
C++11 includes the following new language features:
C++11 includes the following new library features:
Coroutines are special functions that can have their execution suspended and resumed. To define a coroutine, the co_return, co_await, or co_yield keywords must be present in the function's body. C++20's coroutines are stackless; unless optimized out by the compiler, their state is allocated on the heap.
An example of a coroutine is a generator function, which yields (i.e. generates) a value at each invocation:
generator<int> range(int start, int end) { while (start < end) { co_yield start; start++; } // Implicit co_return at the end of this function: // co_return; } for (int n : range(0, 10)) { std::cout << n << std::endl; }
The above range generator function generates values starting at start until end (exclusive), with each iteration step yielding the current value stored in start. The generator maintains its state across each invocation of range (in this case, the invocation is for each iteration in the for loop). co_yield takes the given expression, yields (i.e. returns) its value, and suspends the coroutine at that point. Upon resuming, execution continues after the co_yield.
Another example of a coroutine is a task, which is an asynchronous computation that is executed when the task is awaited:
task<void> echo(socket s) { for (;;) { auto data = co_await s.async_read(); co_await async_write(s, data); } // Implicit co_return at the end of this function: // co_return; }
In this example, the co_await keyword is introduced. This keyword takes an expression and suspends execution if the thing you're awaiting on (in this case, the read or write) is not ready, otherwise you continue execution. (Note that under the hood, co_yield uses co_await.)
Using a task to lazily evaluate a value:
task<int> calculate_meaning_of_life() { co_return 42; } auto meaning_of_life = calculate_meaning_of_life(); // ... co_await meaning_of_life; // == 42
Note: While these examples illustrate how to use coroutines at a basic level, there is lots more going on when the code is compiled. These examples are not meant to be complete coverage of C++20's coroutines. Since the generator and task classes are not provided by the standard library yet, I used the cppcoro library to compile these examples.
Concepts are named compile-time predicates which constrain types. They take the following form:
template < template-parameter-list >
concept concept-name = constraint-expression;
where constraint-expression evaluates to a constexpr Boolean. Constraints should model semantic requirements, such as whether a type is a numeric or hashable. A compiler error results if a given type does not satisfy the concept it's bound by (i.e. constraint-expression returns false). Because constraints are evaluated at compile-time, they can provide more meaningful error messages and runtime safety.
// `T` is not limited by any constraints. template <typename T> concept always_satisfied = true; // Limit `T` to integrals. template <typename T> concept integral = std::is_integral_v<T>; // Limit `T` to both the `integral` constraint and signedness. template <typename T> concept signed_integral = integral<T> && std::is_signed_v<T>; // Limit `T` to both the `integral` constraint and the negation of the `signed_integral` constraint. template <typename T> concept unsigned_integral = integral<T> && !signed_integral<T>;
There are a variety of syntactic forms for enforcing concepts:
// Forms for function parameters: // `T` is a constrained type template parameter. template <my_concept T> void f(T v); // `T` is a constrained type template parameter. template <typename T> requires my_concept<T> void f(T v); // `T` is a constrained type template parameter. template <typename T> void f(T v) requires my_concept<T>; // `v` is a constrained deduced parameter. void f(my_concept auto v); // `v` is a constrained non-type template parameter. template <my_concept auto v> void g(); // Forms for auto-deduced variables: // `foo` is a constrained auto-deduced value. my_concept auto foo = ...; // Forms for lambdas: // `T` is a constrained type template parameter. auto f = []<my_concept T> (T v) { // ... }; // `T` is a constrained type template parameter. auto f = []<typename T> requires my_concept<T> (T v) { // ... }; // `T` is a constrained type template parameter. auto f = []<typename T> (T v) requires my_concept<T> { // ... }; // `v` is a constrained deduced parameter. auto f = [](my_concept auto v) { // ... }; // `v` is a constrained non-type template parameter. auto g = []<my_concept auto v> () { // ... };
The requires keyword is used either to start a requires clause or a requires expression:
template <typename T> requires my_concept<T> // `requires` clause. void f(T); template <typename T> concept callable = requires (T f) { f(); }; // `requires` expression. template <typename T> requires requires (T x) { x + x; } // `requires` clause and expression on same line. T add(T a, T b) { return a + b; }
Note that the parameter list in a requires expression is optional. Each requirement in a requires expression are one of the following:
template <typename T> concept callable = requires (T f) { f(); };
typename keyword followed by a type name, asserts that the given type name is valid.struct foo { int foo; }; struct bar { using value = int; value data; }; struct baz { using value = int; value data; }; // Using SFINAE, enable if `T` is a `baz`. template <typename T, typename = std::enable_if_t<std::is_same_v<T, baz>>> struct S {}; template <typename T> using Ref = T&; template <typename T> concept C = requires { // Requirements on type `T`: typename T::value; // A) has an inner member named `value` typename S<T>; // B) must have a valid class template specialization for `S` typename Ref<T>; // C) must be a valid alias template substitution }; template <C T> void g(T a); g(foo{}); // ERROR: Fails requirement A. g(bar{}); // ERROR: Fails requirement B. g(baz{}); // PASS.
template <typename T> concept C = requires(T x) { {*x} -> std::convertible_to<typename T::inner>; // the type of the expression `*x` is convertible to `T::inner` {x + 1} -> std::same_as<int>; // the expression `x + 1` satisfies `std::same_as<decltype((x + 1))>` {x * 1} -> std::convertible_to<T>; // the type of the expression `x * 1` is convertible to `T` };
requires keyword, specify additional constraints (such as those on local parameter arguments).template <typename T> concept C = requires(T x) { requires std::same_as<sizeof(x), size_t>; };
See also: concepts library.
C-style designated initializer syntax. Any member fields that are not explicitly listed in the designated initializer list are default-initialized.
struct A { int x; int y; int z = 123; }; A a {.x = 1, .z = 2}; // a.x == 1, a.y == 0, a.z == 2
Use familiar template syntax in lambda expressions.
auto f = []<typename T>(std::vector<T> v) { // ... };
This feature simplifies common code patterns, helps keep scopes tight, and offers an elegant solution to a common lifetime problem.
for (auto v = std::vector{1, 2, 3}; auto& e : v) { std::cout << e; } // prints "123"
Provides a hint to the optimizer that the labelled statement has a high probability of being executed.
switch (n) { case 1: // ... break; [[likely]] case 2: // n == 2 is considered to be arbitrarily more // ... // likely than any other value of n break; }
If one of the likely/unlikely attributes appears after the right parenthesis of an if-statement, it indicates that the branch is likely/unlikely to have its substatement (body) executed.
int random = get_random_number_between_x_and_y(0, 3); if (random > 0) [[likely]] { // body of if statement // ... }
It can also be applied to the substatement (body) of an iteration statement.
while (unlikely_truthy_condition) [[unlikely]] { // body of while statement // ... }
Implicitly capturing this in a lambda capture using [=] is now deprecated; prefer capturing explicitly using [=, this] or [=, *this].
struct int_value { int n = 0; auto getter_fn() { // BAD: // return [=]() { return n; }; // GOOD: return [=, *this]() { return n; }; } };
Classes can now be used in non-type template parameters. Objects passed in as template arguments have the type const T, where T is the type of the object, and has static storage duration.
struct foo { foo() = default; constexpr foo(int) {} }; template <foo f> auto get_foo()


免费创建高清无水印Sora视频
Vora是一个免费创建高清无水印Sora视频的AI工具


最适合小白的AI自动化工作流平台
无需编码,轻松生成可复用、可变现的AI自动化工作流

大模型驱动的Excel数据处理工具
基于大模型交互的表格处理系统,允许用户通过对话方式完成数据整理和可视化分析。系统采用机器学习算法解析用户指令,自动执行排序、公式计算和数据透视等操作,支持多种文件格式导入导出。数据处理响应速度保持在0.8秒以内,支持超过100万行数据的即时分析。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


AI论文写作指导平台
AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。


AI一键生成PPT,就用博思AIPPT!
博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频
最新版Sora2模型免费使用,一键生成无水印视频
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号