C++17 有哪些新特性?
What are the new features in C++17?
C++17 现已功能完备,因此不太可能经历大的变化。为 C++17 提出了数百个提案。
哪些特性是在 C++17 中添加到 C++ 中的?
使用支持 "C++1z" 的 C++ 编译器时,当编译器更新到 C++17 时,哪些功能将可用?
语言特点:
模板和通用代码
Template argument deduction for class templates
- 就像函数如何推导出模板参数一样,现在构造函数可以推导出 class
的模板参数
- http://wg21.link/p0433r2 http://wg21.link/p0620r0 http://wg21.link/p0512r0
-
- 表示任何(non-type 模板参数)类型的值。
-
-
-
-
-
拉姆达
-
- 如果符合条件,Lambda 是隐式 constexpr
-
[*this]{ std::cout << could << " be " << useful << '\n'; }
属性
-
-
using
in attributes 以避免重复属性命名空间。
编译器现在 required to ignore non-standard attributes they don't recognize.
- C++14 的措辞允许编译器拒绝未知范围的属性。
语法清理
-
类似于内联函数
编译器选择实例化的地方
-
-
没有字符串的简单static_assert(expression);
no throw
unless throw()
,而throw()
是noexcept(true)
.
清洁器multi-return和流量控制
-
基本上,first-class std::tie
和 auto
例子:
* const auto [it, inserted] = map.insert( {"foo", bar} );
* 创建变量 it
和 inserted
并从 pair
推导出类型 map::insert
returns.
适用于 tuple/pair-likes & std::array
和相对平坦的结构
在标准中实际命名为structured bindings
-
if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)
将if(decl)
扩展到decl
不convertible-to-bool的情况。
Generalizing range-based for loops
- 似乎主要支持哨兵,或与开始迭代器类型不同的结束迭代器,这有助于 null-terminated 循环等。
-
很多人要求的功能来简化 almost-generic 代码。
杂项
-
-
-
- 终于!
- 并非在所有情况下,但将“只是创建一些东西”的语法与“真正的省略”区分开来。
Fixed order-of-evaluation for (some) expressions with some modifications
- 不包括函数参数,但现在禁止函数参数求值交错
- 使一堆损坏的代码大部分工作,并使
.then
用于以后的工作。
-
前进进度保证 (FPG)(另外,FPGs for parallel algorithms)
我认为这是在说“实现可能不会永远停止线程”?
u8'U', u8'T', u8'F', u8'8'
字符文字(字符串已经存在)
-
-
- 测试包含头文件是否会出错
- 几乎可以无缝地从实验迁移到标准
-
inherited constructors fixes to some corner cases (see P0136R0 行为改变示例)
-
-
库添加:
数据类型
-
Almost-always non-empty 上次我查过?
标记联合类型
{很棒|有用}
-
- 也许持有某物之一
- 非常有用
-
- 持有任何东西之一(可复制)
-
std::string
喜欢 reference-to-character-array 或子字符串
- 再也不会
string const&
了。还可以使解析速度快上亿倍。
"hello world"sv
- constexpr
char_traits
std::byte
吃不消。
- 既不是整数也不是字符,只是数据
调用东西
-
- 用一种语法调用任何可调用对象(函数指针、函数、成员指针)。来自标准的 INVOKE 概念
-
- 获取一个 function-like 和一个元组,并将元组解包到调用中。
std::make_from_tuple
,std::apply
应用于对象构造
is_invocable
,is_invocable_r
,invoke_result
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0077r2.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0604r0.html
弃用 result_of
is_invocable<Foo(Args...), R>
是“你能用 Args...
调用 Foo
并获得与 R
兼容的东西吗”,其中 R=void
是默认。
invoke_result<Foo, Args...>
是 std::result_of_t<Foo(Args...)>
但显然不那么令人困惑?
File System TS v1
-
-
-
-
[class.directory_iterator]
and [class.recursive_directory_iterator]
-
fstream
s can be opened with path
s, as well as with const path::value_type*
strings.
New algorithms
for_each_n
reduce
transform_reduce
exclusive_scan
inclusive_scan
transform_exclusive_scan
transform_inclusive_scan
添加用于线程化目的,即使您没有使用它们线程化也会公开
线程
-
- 不定时,不需要时效率更高
atomic<T>
::is_always_lockfree
-
- 在一次锁定多个互斥体时减少一些
std::lock
痛苦。
-
- 2014 年的链接论文,可能已过时
std
算法和相关机器的并行版本
-
(部分)Library Fundamentals TS v1 以上或以下未涵盖
[func.searchers]
and [alg.search]
- 一种搜索算法和技巧
-
- 多态分配器,如
std::function
分配器
- 还有一些standard memory resources to go with it.
- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
std::sample
,从一个范围内抽样?
容器改进
try_emplace
and insert_or_assign
- 在某些情况下提供更好的保证,而虚假 move/copy 会很糟糕
Splicing for map<>
, unordered_map<>
, set<>
, and unordered_set<>
- 以低廉的成本在容器之间移动节点。
- 以低廉的成本合并整个容器。
non-const .data()
为字符串。
non-memberstd::size
, std::empty
, std::data
- 喜欢
std::begin
/end
-
-
-
emplace
函数族 now returns a reference to the created object。
智能指针变化
unique_ptr<T[]>
fixes and other unique_ptr
调整。
weak_from_this
和一些固定为从这里共享
其他 std
数据类型改进:
杂项
C++17库基于C11 instead of C99
- 保留
std[0-9]+
-
大多数 std
实现中公开的实用程序代码
-
科学家可能会喜欢他们
-
std::clamp( a, b, c ) == std::max( b, std::min( a, c ) )
大致
-
-
- 如果你只想在安全的情况下从析构函数中抛出,则需要
-
-
-
-
- 编写模板时非常有用
-
- 类似于
std::less<void>
,但用于根据内容排序的智能指针
-
-
-
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
-
std::is_contiguous_layout,对高效散列很有用
std::to_chars/std::from_chars,高性能,区域无关数字转换;最终 serialize/deserialize 为人类可读格式 (JSON & co)
std::default_order, indirection over std::less
. (breaks ABI of some compilers 由于名称修改,已删除。)
memory_order_consume
,添加了更喜欢使用 memory_order_acquire
的语言
特质
已弃用
- Some C libraries,
- [=262=
result_of
,替换为invoke_result
shared_ptr::unique
,不是很线程安全
Isocpp.org has 有一个独立的自 C++14 以来的变化列表;它已被部分掠夺。
自然TS 的工作是并行进行的,所以有一些TS 是not-quite-ripe 将不得不等待下一次迭代。下一次迭代的目标是之前计划的 C++20,而不是一些谣言暗示的 C++19。 C++1O 已被避免。
初始列表取自 this reddit post and this reddit post,通过谷歌搜索或从上面的 isocpp.org 页面添加了链接。
从 SD-6 feature-test 列表中掠夺的其他条目。
clang's feature list and library feature list 是下一个被掠夺的地方。这似乎不可靠,因为它是 C++1z,而不是 C++17。
these slides 其他地方缺少一些功能。
虽然没有询问“删除了什么”,但这里是一些在 C++17 中从 C++ 中删除的内容((主要是?)以前弃用的)的简短列表:
已删除:
register
,为将来使用保留的关键字
bool b; ++b;
- trigraphs
- 如果您仍然需要它们,它们现在是源文件编码的一部分,而不是语言的一部分
- ios aliases
- auto_ptr, old
<functional>
stuff, random_shuffle
- allocators in
std::function
有重写。我不确定这些是否对代码有任何影响,或者它们是否只是标准中的清理:
以上未整合的论文:
P0505R0 (constexpr chrono)
P0418R2(原子调整)
P0512R0(模板参数推导调整)
P0490R0(结构化绑定调整)
P0513R0(更改为 std::hash
)
P0502R0(并行异常)
P0509R1(更新异常处理限制)
P0012R1(使异常规范成为类型系统的一部分)
P0510R0(变体限制)
P0504R0(optional/variant/any 的标签)
P0497R0(共享指针调整)
P0508R0(结构化绑定节点句柄)
P0521R0(共享指针使用次数和唯一变化?)
规格变更:
进一步参考:
C++17 现已功能完备,因此不太可能经历大的变化。为 C++17 提出了数百个提案。
哪些特性是在 C++17 中添加到 C++ 中的?
使用支持 "C++1z" 的 C++ 编译器时,当编译器更新到 C++17 时,哪些功能将可用?
语言特点:
模板和通用代码
Template argument deduction for class templates
- 就像函数如何推导出模板参数一样,现在构造函数可以推导出 class 的模板参数
- http://wg21.link/p0433r2 http://wg21.link/p0620r0 http://wg21.link/p0512r0
-
- 表示任何(non-type 模板参数)类型的值。
拉姆达
-
- 如果符合条件,Lambda 是隐式 constexpr
-
[*this]{ std::cout << could << " be " << useful << '\n'; }
属性
using
in attributes 以避免重复属性命名空间。编译器现在 required to ignore non-standard attributes they don't recognize.
- C++14 的措辞允许编译器拒绝未知范围的属性。
语法清理
类似于内联函数
编译器选择实例化的地方
没有字符串的简单
static_assert(expression);
no
throw
unlessthrow()
,而throw()
是noexcept(true)
.
清洁器multi-return和流量控制
基本上,first-class
std::tie
和auto
例子: *
const auto [it, inserted] = map.insert( {"foo", bar} );
* 创建变量it
和inserted
并从pair
推导出类型map::insert
returns.适用于 tuple/pair-likes &
std::array
和相对平坦的结构在标准中实际命名为structured bindings
if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)
将
if(decl)
扩展到decl
不convertible-to-bool的情况。Generalizing range-based for loops
- 似乎主要支持哨兵,或与开始迭代器类型不同的结束迭代器,这有助于 null-terminated 循环等。
很多人要求的功能来简化 almost-generic 代码。
杂项
-
- 终于!
- 并非在所有情况下,但将“只是创建一些东西”的语法与“真正的省略”区分开来。
Fixed order-of-evaluation for (some) expressions with some modifications
- 不包括函数参数,但现在禁止函数参数求值交错
- 使一堆损坏的代码大部分工作,并使
.then
用于以后的工作。
前进进度保证 (FPG)(另外,FPGs for parallel algorithms)
我认为这是在说“实现可能不会永远停止线程”?
u8'U', u8'T', u8'F', u8'8'
字符文字(字符串已经存在)-
- 测试包含头文件是否会出错
- 几乎可以无缝地从实验迁移到标准
inherited constructors fixes to some corner cases (see P0136R0 行为改变示例)
库添加:
数据类型
Almost-always non-empty 上次我查过?
标记联合类型
{很棒|有用}
-
- 也许持有某物之一
- 非常有用
-
- 持有任何东西之一(可复制)
-
std::string
喜欢 reference-to-character-array 或子字符串- 再也不会
string const&
了。还可以使解析速度快上亿倍。 "hello world"sv
- constexpr
char_traits
std::byte
吃不消。- 既不是整数也不是字符,只是数据
调用东西
-
- 用一种语法调用任何可调用对象(函数指针、函数、成员指针)。来自标准的 INVOKE 概念
-
- 获取一个 function-like 和一个元组,并将元组解包到调用中。
std::make_from_tuple
,std::apply
应用于对象构造is_invocable
,is_invocable_r
,invoke_result
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0077r2.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0604r0.html
弃用
result_of
is_invocable<Foo(Args...), R>
是“你能用Args...
调用Foo
并获得与R
兼容的东西吗”,其中R=void
是默认。invoke_result<Foo, Args...>
是std::result_of_t<Foo(Args...)>
但显然不那么令人困惑?
File System TS v1
[class.directory_iterator]
and[class.recursive_directory_iterator]
fstream
s can be opened withpath
s, as well as withconst path::value_type*
strings.
New algorithms
for_each_n
reduce
transform_reduce
exclusive_scan
inclusive_scan
transform_exclusive_scan
transform_inclusive_scan
添加用于线程化目的,即使您没有使用它们线程化也会公开
线程
-
- 不定时,不需要时效率更高
atomic<T>
::is_always_lockfree
-
- 在一次锁定多个互斥体时减少一些
std::lock
痛苦。
- 在一次锁定多个互斥体时减少一些
-
- 2014 年的链接论文,可能已过时
std
算法和相关机器的并行版本
(部分)Library Fundamentals TS v1 以上或以下未涵盖
[func.searchers]
and[alg.search]
- 一种搜索算法和技巧
-
- 多态分配器,如
std::function
分配器 - 还有一些standard memory resources to go with it.
- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
- 多态分配器,如
std::sample
,从一个范围内抽样?
容器改进
try_emplace
andinsert_or_assign
- 在某些情况下提供更好的保证,而虚假 move/copy 会很糟糕
Splicing for
map<>
,unordered_map<>
,set<>
, andunordered_set<>
- 以低廉的成本在容器之间移动节点。
- 以低廉的成本合并整个容器。
non-const
.data()
为字符串。non-member
std::size
,std::empty
,std::data
- 喜欢
std::begin
/end
- 喜欢
emplace
函数族 now returns a reference to the created object。
智能指针变化
unique_ptr<T[]>
fixes and otherunique_ptr
调整。weak_from_this
和一些固定为从这里共享
其他 std
数据类型改进:
杂项
C++17库基于C11 instead of C99
- 保留
std[0-9]+
大多数
std
实现中公开的实用程序代码科学家可能会喜欢他们
-
std::clamp( a, b, c ) == std::max( b, std::min( a, c ) )
大致
-
- 如果你只想在安全的情况下从析构函数中抛出,则需要
-
- 编写模板时非常有用
-
- 类似于
std::less<void>
,但用于根据内容排序的智能指针
- 类似于
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
std::is_contiguous_layout,对高效散列很有用
std::to_chars/std::from_chars,高性能,区域无关数字转换;最终 serialize/deserialize 为人类可读格式 (JSON & co)
std::default_order, indirection over(breaks ABI of some compilers 由于名称修改,已删除。)std::less
.
的语言memory_order_consume
,添加了更喜欢使用memory_order_acquire
特质
已弃用
- Some C libraries,
- [=262=
result_of
,替换为invoke_result
shared_ptr::unique
,不是很线程安全
Isocpp.org has 有一个独立的自 C++14 以来的变化列表;它已被部分掠夺。
自然TS 的工作是并行进行的,所以有一些TS 是not-quite-ripe 将不得不等待下一次迭代。下一次迭代的目标是之前计划的 C++20,而不是一些谣言暗示的 C++19。 C++1O 已被避免。
初始列表取自 this reddit post and this reddit post,通过谷歌搜索或从上面的 isocpp.org 页面添加了链接。
从 SD-6 feature-test 列表中掠夺的其他条目。
clang's feature list and library feature list 是下一个被掠夺的地方。这似乎不可靠,因为它是 C++1z,而不是 C++17。
these slides 其他地方缺少一些功能。
虽然没有询问“删除了什么”,但这里是一些在 C++17 中从 C++ 中删除的内容((主要是?)以前弃用的)的简短列表:
已删除:
register
,为将来使用保留的关键字bool b; ++b;
- trigraphs
- 如果您仍然需要它们,它们现在是源文件编码的一部分,而不是语言的一部分
- ios aliases
- auto_ptr, old
<functional>
stuff,random_shuffle
- allocators in
std::function
有重写。我不确定这些是否对代码有任何影响,或者它们是否只是标准中的清理:
以上未整合的论文:
P0505R0 (constexpr chrono)
P0418R2(原子调整)
P0512R0(模板参数推导调整)
P0490R0(结构化绑定调整)
P0513R0(更改为
std::hash
)P0502R0(并行异常)
P0509R1(更新异常处理限制)
P0012R1(使异常规范成为类型系统的一部分)
P0510R0(变体限制)
P0504R0(optional/variant/any 的标签)
P0497R0(共享指针调整)
P0508R0(结构化绑定节点句柄)
P0521R0(共享指针使用次数和唯一变化?)