modern-cpp-features

modern-cpp-features

C++20/17/14/11新特性概览

项目提供C++20/17/14/11新特性概览,涵盖各版本引入的语言和库功能。包括C++20的协程、概念、指定初始化器,C++17的变体、可选值、文件系统,以及C++14和C++11的主要更新。为开发者提供现代C++新特性的参考资源,便于快速了解语言演进。

C++20C++17C++14C++11语言特性Github开源项目

C++20/17/14/11

Overview

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:

C++20 Language Features

Coroutines

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

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:

  • Simple requirements - asserts that the given expression is valid.
template <typename T> concept callable = requires (T f) { f(); };
  • Type requirements - denoted by the 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.
  • Compound requirements - an expression in braces followed by a trailing return type or type constraint.
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` };
  • Nested requirements - denoted by the 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.

Designated initializers

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

Template syntax for lambdas

Use familiar template syntax in lambda expressions.

auto f = []<typename T>(std::vector<T> v) { // ... };

Range-based for loop with initializer

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"

[[likely]] and [[unlikely]] attributes

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 // ... }

Deprecate implicit capture of this

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; }; } };

Class types in non-type template parameters

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()

编辑推荐精选

音述AI

音述AI

全球首个AI音乐社区

音述AI是全球首个AI音乐社区,致力让每个人都能用音乐表达自我。音述AI提供零门槛AI创作工具,独创GETI法则帮助用户精准定义音乐风格,AI润色功能支持自动优化作品质感。音述AI支持交流讨论、二次创作与价值变现。针对中文用户的语言习惯与文化背景进行专门优化,支持国风融合、C-pop等本土音乐标签,让技术更好地承载人文表达。

QoderWork

QoderWork

阿里Qoder团队推出的桌面端AI智能体

QoderWork 是阿里推出的本地优先桌面 AI 智能体,适配 macOS14+/Windows10+,以自然语言交互实现文件管理、数据分析、AI 视觉生成、浏览器自动化等办公任务,自主拆解执行复杂工作流,数据本地运行零上传,技能市场可无限扩展,是高效的 Agentic 生产力办公助手。

lynote.ai

lynote.ai

一站式搞定所有学习需求

不再被海量信息淹没,开始真正理解知识。Lynote 可摘要 YouTube 视频、PDF、文章等内容。即时创建笔记,检测 AI 内容并下载资料,将您的学习效率提升 10 倍。

AniShort

AniShort

为AI短剧协作而生

专为AI短剧协作而生的AniShort正式发布,深度重构AI短剧全流程生产模式,整合创意策划、制作执行、实时协作、在线审片、资产复用等全链路功能,独创无限画布、双轨并行工业化工作流与Ani智能体助手,集成多款主流AI大模型,破解素材零散、版本混乱、沟通低效等行业痛点,助力3人团队效率提升800%,打造标准化、可追溯的AI短剧量产体系,是AI短剧团队协同创作、提升制作效率的核心工具。

seedancetwo2.0

seedancetwo2.0

能听懂你表达的视频模型

Seedance two是基于seedance2.0的中国大模型,支持图像、视频、音频、文本四种模态输入,表达方式更丰富,生成也更可控。

nano-banana纳米香蕉中文站

nano-banana纳米香蕉中文站

国内直接访问,限时3折

输入简单文字,生成想要的图片,纳米香蕉中文站基于 Google 模型的 AI 图片生成网站,支持文字生图、图生图。官网价格限时3折活动

扣子-AI办公

扣子-AI办公

职场AI,就用扣子

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

堆友

堆友

多风格AI绘画神器

堆友平台由阿里巴巴设计团队创建,作为一款AI驱动的设计工具,专为设计师提供一站式增长服务。功能覆盖海量3D素材、AI绘画、实时渲染以及专业抠图,显著提升设计品质和效率。平台不仅提供工具,还是一个促进创意交流和个人发展的空间,界面友好,适合所有级别的设计师和创意工作者。

图像生成AI工具AI反应堆AI工具箱AI绘画GOAI艺术字堆友相机AI图像热门
码上飞

码上飞

零代码AI应用开发平台

零代码AI应用开发平台,用户只需一句话简单描述需求,AI能自动生成小程序、APP或H5网页应用,无需编写代码。

Vora

Vora

免费创建高清无水印Sora视频

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

下拉加载更多