C++17 有哪些新特性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38060436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the new features in C++17?
提问by Yakk - Adam Nevraumont
C++17 is now feature complete, so unlikely to experience large changes. Hundreds of proposals were put forward for C++17.
C++17 现在功能完整,所以不太可能经历大的变化。为 C++17 提出了数百个提案。
Which of those features were added to C++ in C++17?
在 C++17 中,C++ 中添加了哪些特性?
When using a C++ compiler that supports "C++1z", which of those features are going to be available when the compiler updates to C++17?
当使用支持“C++1z”的 C++ 编译器时,当编译器更新到 C++17 时,哪些特性将可用?
回答by Yakk - Adam Nevraumont
Language features:
语言特点:
Templates and Generic Code
模板和通用代码
Template argument deduction for class templates
- Like how functions deduce template arguments, now constructors can deduce the template arguments of the class
- http://wg21.link/p0433r2http://wg21.link/p0620r0http://wg21.link/p0512r0
- Represents a value of any (non-type template argument) type.
- 就像函数如何推导出模板参数一样,现在构造函数可以推导出类的模板参数
- http://wg21.link/p0433r2 http://wg21.link/p0620r0 http://wg21.link/p0512r0
- 表示任何(非类型模板参数)类型的值。
Lambda
拉姆达
- Lambdas are implicitly constexpr if they qualify
[*this]{ std::cout << could << " be " << useful << '\n'; }
- 如果 Lambda 符合条件,则隐式为 constexpr
[*this]{ std::cout << could << " be " << useful << '\n'; }
Attributes
属性
[[fallthrough]]
,[[nodiscard]]
,[[maybe_unused]]
attributesusing
in attributesto avoid having to repeat an attribute namespace.Compilers are now required to ignore non-standard attributes they don't recognize.
- The C++14 wording allowed compilers to reject unknown scoped attributes.
using
在属性中以避免重复属性命名空间。现在要求编译器忽略他们不认识的非标准属性。
- C++14 的措辞允许编译器拒绝未知范围的属性。
Syntax cleanup
语法清理
- Like inline functions
- Compiler picks where the instance is instantiated
- Deprecate static constexpr redeclaration, now implicitly inline.
Simple
static_assert(expression);
with no stringno
throw
unlessthrow()
, andthrow()
isnoexcept(true)
.
- 像内联函数
- 编译器选择实例化的位置
- 弃用静态 constexpr 重新声明,现在隐式内联。
简单
static_assert(expression);
没有字符串没有
throw
除非throw()
,并且throw()
是noexcept(true)
。
Cleaner multi-return and flow control
更清洁的多回程和流量控制
- Basically, first-class
std::tie
withauto
- Example:
const auto [it, inserted] = map.insert( {"foo", bar} );
- Creates variables
it
andinserted
with deduced type from thepair
thatmap::insert
returns.
- Works with tuple/pair-likes &
std::array
s and relatively flat structs - Actually named structured bindingsin standard
- Basically, first-class
if (init; condition)
andswitch (init; condition)
if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)
- Extends the
if(decl)
to cases wheredecl
isn't convertible-to-bool sensibly.
Generalizing range-based for loops
- Appears to be mostly support for sentinels, or end iterators that are not the same type as begin iterators, which helps with null-terminated loops and the like.
- Much requested feature to simplify almost-generic code.
- 基本上,一流
std::tie
的auto
- 例子:
const auto [it, inserted] = map.insert( {"foo", bar} );
- 创建变量
it
并inserted
从与推导的类型pair
是map::insert
回报。
- 适用于 tuple/pair-likes &
std::array
s 和相对扁平的结构 - 标准中实际命名的结构化绑定
- 基本上,一流
if (init; condition)
和switch (init; condition)
if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)
- 扩展
if(decl)
到decl
不能转换为布尔值的情况。
- 似乎主要支持哨兵,或者与开始迭代器类型不同的结束迭代器,这有助于以空终止循环等。
- 许多要求的功能可以简化几乎通用的代码。
Misc
杂项
- Finally!
- Not in all cases, but distinguishes syntax where you are "just creating something" that was called elision, from "genuine elision".
Fixed order-of-evaluation for (some) expressionswith some modifications
- Not including function arguments, but function argument evaluation interleaving now banned
- Makes a bunch of broken code work mostly, and makes
.then
on future work.
Forward progress guarantees (FPG) (also, FPGs for parallel algorithms)
- I think this is saying "the implementation may not stall threads forever"?
u8'U', u8'T', u8'F', u8'8'
character literals (string already existed)- Test if a header file include would be an error
- makes migrating from experimental to std almost seamless
inherited constructorsfixes to some corner cases (see P0136R0for examples of behavior changes)
- 最后!
- 并非在所有情况下,而是将语法与“真正的省略”区分开来,即您“只是创建某些东西”(称为省略)。
- 不包括函数参数,但现在禁止函数参数评估交错
- 使一堆损坏的代码大部分工作,并
.then
在未来的工作中发挥作用。
前向进度保证 (FPG)(还有用于并行算法的FPG )
- 我认为这是说“实现可能不会永远停止线程”?
u8'U', u8'T', u8'F', u8'8'
字符文字(字符串已经存在)- 测试头文件包含是否会出错
- 使从实验到标准的迁移几乎无缝
Library additions:
图书馆补充:
Data types
数据类型
- Almost-always non-empty last I checked?
- Tagged union type
- {awesome|useful}
- Maybe holds one of something
- Ridiculously useful
- Holds one of anything (that is copyable)
std::string
like reference-to-character-array or substring- Never take a
string const&
again. Also can make parsing a bajillion times faster. "hello world"sv
- constexpr
char_traits
std::byte
off more than they could chew.- Neither an integer nor a character, just data
- 我上次检查时几乎总是非空的?
- 标记联合类型
- {真棒|有用}
- 也许持有某物之一
- 非常有用
- 持有任何东西之一(可复制)
std::string
像对字符数组或子字符串的引用- 再也不拿了
string const&
。还可以使解析速度快 bajillion 倍。 "hello world"sv
- 常量表达式
char_traits
std::byte
关闭超过他们可以咀嚼。- 既不是整数也不是字符,只是数据
Invoke stuff
调用东西
std::invoke
- Call any callable (function pointer, function, member pointer) with one syntax. From the standard INVOKE concept.
std::apply
- Takes a function-like and a tuple, and unpacks the tuple into the call.
std::make_from_tuple
,std::apply
applied to object constructionis_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
- Deprecates
result_of
is_invocable<Foo(Args...), R>
is "can you callFoo
withArgs...
and get something compatible withR
", whereR=void
is default.invoke_result<Foo, Args...>
isstd::result_of_t<Foo(Args...)>
but apparently less confusing?
std::invoke
- 使用一种语法调用任何可调用对象(函数指针、函数、成员指针)。来自标准的 INVOKE 概念。
std::apply
- 接受一个类函数和一个元组,并将元组解包到调用中。
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>
是“能打电话Foo
与Args...
并获得兼容的东西R
”,这里R=void
是默认的。invoke_result<Foo, Args...>
是std::result_of_t<Foo(Args...)>
,但显然不太混淆?
File System TS v1
文件系统 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
Added for threading purposes, exposed even if you aren't using them threaded
for_each_n
reduce
transform_reduce
exclusive_scan
inclusive_scan
transform_exclusive_scan
transform_inclusive_scan
添加用于线程目的,即使您不使用线程也会暴露
Threading
穿线
- Untimed, which can be more efficient if you don't need it.
atomic<T>
::is_always_lockfree
- Saves some
std::lock
pain when locking more than one mutex at a time.
- Saves some
- The linked paper from 2014, may be out of date
- Parallel versions of
std
algorithms, and related machinery
- 不定时,如果你不需要它可以更有效。
atomic<T>
::is_always_lockfree
std::lock
一次锁定多个互斥体时可以省去一些麻烦。
- 2014 年的链接论文可能已过时
- 并行版本的
std
算法和相关机器
(parts of) Library Fundamentals TS v1not covered above or below
上面或下面未涵盖的(部分)库基础知识 TS v1
[func.searchers]
and[alg.search]
- A searching algorithm and techniques
- Polymorphic allocator, like
std::function
for allocators - And some standard memory resources to go with it.
- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
- Polymorphic allocator, like
std::sample
, sampling from a range?
[func.searchers]
和[alg.search]
- 一种搜索算法和技术
- 多态分配器,就像
std::function
分配器一样 - 还有一些标准的内存资源与之配套。
- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
- 多态分配器,就像
std::sample
,从一个范围抽样?
Container Improvements
容器改进
try_emplace
andinsert_or_assign
- gives better guarantees in some cases where spurious move/copy would be bad
Splicing for
map<>
,unordered_map<>
,set<>
, andunordered_set<>
- Move nodes between containers cheaply.
- Merge whole containers cheaply.
non-const
.data()
for string.non-member
std::size
,std::empty
,std::data
- like
std::begin
/end
- like
The
emplace
family of functions now returns a reference to the created object.
- 在某些虚假移动/复制不好的情况下提供更好的保证
拼接
map<>
,unordered_map<>
,set<>
, 和unordered_set<>
- 廉价地在容器之间移动节点。
- 便宜地合并整个容器。
非const
.data()
字符串。非会员
std::size
,std::empty
,std::data
- 喜欢
std::begin
/end
- 喜欢
该
emplace
系列函数现在返回到创建对象的引用。
Smart pointer changes
智能指针变化
unique_ptr<T[]>
fixesand otherunique_ptr
tweaks.weak_from_this
and some fixed to shared from this
unique_ptr<T[]>
修复和其他unique_ptr
调整。weak_from_this
和一些固定从这里共享
Other std
datatype improvements:
其他std
数据类型改进:
{}
construction ofstd::tuple
and other improvements- TriviallyCopyable reference_wrapper, can be performance boost
Misc
杂项
C++17 library is based on C11 instead of C99
Reserved
std[0-9]+
for future standard libraries- utility code already in most
std
implementations exposed
- utility code already in most
- Special math functions
- scientists may like them
std::clamp()
std::clamp( a, b, c ) == std::max( b, std::min( a, c ) )
roughly
gcd
andlcm
std::uncaught_exceptions
- Required if you want to only throw if safe from destructors
std::as_const
std::bool_constant
- A whole bunch of
_v
template variables std::void_t<T>
- Surprisingly useful when writing templates
std::owner_less<void>
- like
std::less<void>
, but for smart pointers to sort based on contents
- like
std::chrono
polishstd::conjunction
,std::disjunction
,std::negation
exposedstd::not_fn
- Rules for noexcept within
std
- std::is_contiguous_layout, useful for efficient hashing
- std::to_chars/std::from_chars, high performance, locale agnostic number conversion; finally a way to serialize/deserialize to human readable formats (JSON & co)
std::default_order, indirection over(breaks ABI of some compilersdue to name mangling, removed.)std::less
.
C++17 库基于C11 而不是 C99
std[0-9]+
为未来的标准库保留- 大多数
std
实现中已经公开的实用程序代码
- 大多数
- 特殊数学函数
- 科学家们可能会喜欢它们
std::clamp()
std::clamp( a, b, c ) == std::max( b, std::min( a, c ) )
大致
gcd
和lcm
std::uncaught_exceptions
- 如果您只想在不受析构函数安全的情况下抛出,则是必需的
std::as_const
std::bool_constant
- 一大堆
_v
模板变量 std::void_t<T>
- 在编写模板时非常有用
std::owner_less<void>
- 喜欢
std::less<void>
,但智能指针基于内容排序
- 喜欢
std::chrono
抛光std::conjunction
,std::disjunction
,std::negation
暴露std::not_fn
- 内 noexcept 的规则
std
- std::is_contiguous_layout,用于高效散列
- std::to_chars/std::from_chars,高性能,与语言环境无关的数字转换;最后一种序列化/反序列化为人类可读格式的方法(JSON & co)
std::default_order,间接超过(由于名称修改而破坏了某些编译器的 ABI,已删除。)std::less
.
Traits
性状
Deprecated
已弃用
- Some C libraries,
<codecvt>
memory_order_consume
result_of
, replaced withinvoke_result
shared_ptr::unique
, it isn't very threadsafe
- 一些 C 库,
<codecvt>
memory_order_consume
result_of
,替换为invoke_result
shared_ptr::unique
,它不是很线程安全
Isocpp.org hashas an independent list of changes since C++14; it has been partly pillaged.
Isocpp.org 拥有自 C++14 以来的独立变更列表;它已被部分掠夺。
Naturally TS work continues in parallel, so there are some TS that are not-quite-ripe that will have to wait for the next iteration. The target for the next iteration is C++20 as previously planned, not C++19 as some rumors implied. C++1O has been avoided.
自然地,TS 工作并行继续,因此有些 TS 尚未成熟,将不得不等待下一次迭代。下一次迭代的目标是之前计划的 C++20,而不是一些传言暗示的 C++19。已避免使用 C++1O。
Initial list taken from this reddit postand this reddit post, with links added via googling or from the above isocpp.org page.
从这个 reddit 帖子和这个 reddit 帖子中获取的初始列表,通过谷歌搜索或从上面的 isocpp.org 页面添加了链接。
Additional entries pillaged from SD-6feature-test list.
从SD-6功能测试列表中掠夺的其他条目。
clang's feature listand library feature listare next to be pillaged. This doesn't seem to be reliable, as it is C++1z, not C++17.
clang 的功能列表和库功能列表即将被掠夺。这似乎不可靠,因为它是 C++1z,而不是 C++17。
these slideshad some features missing elsewhere.
这些幻灯片在其他地方缺少一些功能。
While "what was removed" was not asked, here is a short list of a few things ((mostly?) previous deprecated) that are removed in C++17 from C++:
虽然没有询问“删除了什么”,但这里列出了在 C++17 中从 C++ 中删除的一些内容((大部分?)以前已弃用):
Removed:
删除:
register
, keyword reserved for future usebool b; ++b;
- trigraphs
- if you still need them, they are now part of your source file encoding, not part of language
- ios aliases
- auto_ptr, old
<functional>
stuff,random_shuffle
- allocators in
std::function
register
, 保留关键字供将来使用bool b; ++b;
- 三合字母
- 如果您仍然需要它们,它们现在是您的源文件编码的一部分,而不是语言的一部分
- ios别名
- auto_ptr,旧的
<functional>
东西,random_shuffle
- 分配器
std::function
There were rewordings. I am unsure if these have any impact on code, or if they are just cleanups in the standard:
有改写。我不确定这些是否对代码有任何影响,或者它们是否只是标准中的清理:
Papers not yet integrated into above:
尚未整合到上面的论文:
P0505R0(constexpr chrono)
P0418R2(atomic tweaks)
P0512R0(template argument deduction tweaks)
P0490R0(structured binding tweaks)
P0513R0(changes to
std::hash
)P0502R0(parallel exceptions)
P0509R1(updating restrictions on exception handling)
P0012R1(make exception specifications be part of the type system)
P0510R0(restrictions on variants)
P0504R0(tags for optional/variant/any)
P0497R0(shared ptr tweaks)
P0508R0(structured bindings node handles)
P0521R0(shared pointer use count and unique changes?)
P0505R0(constexpr 计时)
P0418R2(原子调整)
P0512R0(模板参数推导调整)
P0490R0(结构化绑定调整)
P0513R0(更改为
std::hash
)P0502R0(并行异常)
P0509R1(更新异常处理限制)
P0012R1(使异常规范成为类型系统的一部分)
P0510R0(变体限制)
P0504R0(可选/变体/任何标签)
P0497R0(共享 ptr 调整)
P0508R0(结构化绑定节点句柄)
P0521R0(共享指针使用计数和唯一更改?)
Spec changes:
规格变化:
Further reference:
进一步参考:
https://isocpp.org/files/papers/p0636r0.html
- Should be updated to "Modifications to existing features" here.
https://isocpp.org/files/papers/p0636r0.html
- 应在此处更新为“对现有功能的修改”。