提问



C ++ 17现在功能齐全,因此不太可能经历大的变化。为C ++ 17提出了数百个提案。


在C ++ 17中,哪些特性被添加到C ++中?


当使用支持C ++ 1z的C ++编译器时,当编译器更新到C ++ 17时,哪些功能可用?

最佳参考


语言功能:



模板和通用代码




  • 类模板的模板参数推导[146]



    • 与函数如何推导模板参数一样,现在构造函数可以推导出类
    • 的模板参数
    • http://wg21.link/p0433r2 http://wg21.link/p0620r0 http://wg21.link/p0512r0


  • template <auto> [147] [148] [149] [150]



    • 表示任何(非类型模板参数)类型的值。


  • 非类型模板参数修复[151]

  • template<template<class...>typename bob> struct foo {} [152]

  • (折叠+ ... +表达)和修订[153] [154]

  • auto x{8};int [155]

  • ...进行现代化using并列出[156]



LAMBDA




  • constexpr lambdas [157]



    • Lambdas如果符合条件,则隐含constexpr


  • 在lambdas [158]中捕捉*this



    • [*this]{ std::cout << could << " be " << useful << '\n'; }




属性




  • [**fallthrough**][**nodiscard**][**maybe_unused**]属性[159] [160] [161]

  • [**attributes**]关于namespaceenum { erator[**s**] } [162]

  • using在属性中避免重复属性名称空间。[163]

  • 编译器现在需要忽略他们不认识的非标准属性。[164]



    • C ++ 14措辞允许编译器拒绝未知的范围属性。




语法清理




  • 内联变量[165]



    • 与内联函数一样

    • 编译器选择实例实例化的地方

    • 弃用静态constexpr重新声明,现在隐式内联。


  • namespace A::B [166] [167]

  • 简单static_assert(expression);没有字符串[168]

  • throw除非throw()throw()noexcept(true)[169]



清除多回程和流量控制




  • 结构化绑定[170]



    • 基本上,autoauto
    • 的一流std::tie
    • 实施例:


      • const auto [it, inserted] = map.insert( {"foo", bar} );

      • 使用pair返回的pair中的推导类型创建变量itinserted


    • 使用元组/对喜欢& std::array和相对扁平的结构

    • 实际上在标准
    • 中命名了结构化绑定

  • if (init; condition)switch (init; condition) [171] [172]



    • if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)

    • if(decl)扩展到decl不能明智地转换为布尔的情况。


  • 基于范围的广义循环[173]



    • 似乎主要支持哨兵,或者结束与开始迭代器类型不同的迭代器,这有助于使用以null结尾的循环等。


  • if constexpr [174]



    • 要求简化几乎通用代码的功能。




其它




  • 十六进制浮点文字[175]

  • 过度对齐数据的动态内存分配[176]

  • 保证副本省略[177]



    • 最后!

    • 并非在所有情况下都可以区分语法,即真正的省略,即正在创造某种东西,即真正的省略。


  • 修正(某些)某些表达方式的评估顺序[178] [179]



    • 不包括函数参数,但函数参数评估交错现在被禁止

    • 使一堆破碎的代码主要工作,并使.then在未来工作。


  • 枚举的直接列表初始化[180]

  • 正向进度保证(FPG)(也是并行算法的FPG)[181]



    • 我认为这说实施可能不会永远拖延线程?


  • u8'U', u8'T', u8'F', u8'8'字符文字(字符串已存在)[182]

  • 类型系统中的
  • noexcept[183]​​]]

  • __has_include [184]



    • 测试头文件是否包含错误

    • 使从实验迁移到std几乎无缝


  • 指针转换修复阵列[185]

  • 继承的构造函数修复了一些极端情况(有关行为更改的示例,请参阅P0136R0)[186] [187]

  • 使用继承进行聚合初始化。[188]

  • std::launder,打字等等[189]



图书馆补充:



数据类型




  • std::variant<Ts...> [190]



    • 我最后检查几乎总是非空的?

    • 标记联合类型

    • {真棒|有用}


  • std::optional [191]



    • 也许拥有某种东西

    • 非常有用


  • std::any [192]



    • 保留任何内容(可复制)


  • std::string_view [193]



    • std::string类似于引用字符数组或子字符串

    • 再也不要string const&。也可以使解析速度提高5倍。

    • "hello world"sv

    • constexpr char_traits


  • std::byte比他们咀嚼更多。[194] [195] [196]



    • 既不是整数也不是字符,只是数据




调用内容




  • std::invoke


    • 使用一种语法调用任何可调用的(函数指针,函数,成员指针)。来自标准的INVOKE概念。


  • std::apply


    • 使用类似函数和元组,并将元组解包到调用中。


  • std::make_from_tuplestd::apply适用于对象构造[197] [198] [199]

  • is_invocableis_invocable_rinvoke_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...)>,但显然不那么令人困惑?




文件系统TS v1




  • [class.path] [200] [201] [202] [203]

  • [class.filesystem.error] [204]

  • [class.file_status] [205]

  • [class.directory_entry] [206]

  • [class.directory_iterator][class.recursive_directory_iterator] [207] [208]

  • [fs.ops.funcs] [209]

  • fstream s可以用path s以及const path::value_type*字符串打开。[210]



新算法




  • for_each_n [211]

  • reduce

  • transform_reduce

  • exclusive_scan

  • inclusive_scan

  • transform_exclusive_scan

  • transform_inclusive_scan

  • 添加用于线程目的,即使您没有使用它们也会暴露



线程




  • std::shared_mutex [212]



    • 不定时,如果你不需要它可以更有效率。


  • atomic<T> ::is_always_lockfree [213]

  • scoped_lock<Mutexes...> [214]



    • 一次锁定多个互斥锁时会节省一些std::lock疼痛。


  • Parallelism TS v1 [215]



    • 2014年的关联论文可能已过期

    • std算法和相关机器的并行版本


  • 硬件_ * _ interference_size [216]



(部分)库基础知识TS v1未在上文或下文中介绍




  • [func.searchers][alg.search]


    • 搜索算法和技术


  • [pmr] [217] [218] [219] [220]



    • 多态分配器,如分配器的std::function

    • 和一些标准的内存资源一起使用。

    • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html


  • std::sample,从范围内抽样?[221] [222] [223]



容器改进




  • try_emplaceinsert_or_assign [224] [225]



    • 在虚假移动/复制不好的某些情况下提供更好的保证


  • map<>unordered_map<>set<>unordered_set<> [226]的拼接



    • 便宜地在容器之间移动节点。

    • 便宜地合并整个容器。


  • 字符串的非常量.data()[227]

  • 非会员std::sizestd::emptystd::data [228]



    • 喜欢std::begin/end


  • 容器中的最小不完整类型支持[229]

  • 连续迭代器概念[230]

  • constexpr迭代器[231]

  • emplace系列函数现在返回对创建对象的引用。[232]



智能指针更改




  • unique_ptr<T[]>修正和其他unique_ptr调整。

  • weak_from_this以及一些已修复为
  • 的共享


其他std数据类型改进:




  • {} std::tuple的构建及其他改进

  • TriviallyCopyable reference_wrapper,可以提升性能



其它




  • C ++ 17库基于C11而不是C99 [233] [234] [235] [236] [237] [238]

  • 为未来的标准库保留std[0-9]+ [239]

  • destroy(_at|_n)uninitialized_move(_n)uninitialized_value_construct(_n)uninitialized_default_construct(_n) [240]



    • 实用程序代码已经暴露在大多数std实现中


  • 特殊数学函数


    • 科学家可能喜欢他们


  • std::clamp()


    • std::clamp( a, b, c ) == std::max( b, std::min( a, c ) )粗略


  • gcdlcm

  • std::uncaught_exceptions


    • 如果您只想从析构函数中安全抛出
    • ,则为必需

  • std::as_const

  • std::bool_constant

  • 一大堆_v模板变量

  • std::void_t<T>


    • 撰写模板时非常有用


  • std::owner_less<void>


    • 喜欢std::less<void>,但是对于基于内容排序的智能指针


  • std::chrono polish

  • std::conjunctionstd::disjunctionstd::negation暴露

  • std::not_fn


    • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html


  • std
  • 中的noexcept规则
  • std :: is_contiguous_layout,对高效散列非常有用

  • std :: to_chars/std :: from_chars,高性能,区域设置不可知的数字转换;最后一种序列化/反序列化为人类可读格式的方法(JSON& co)

  • std :: default_order,inirection over std::less(由于名称修改而删除了一些编译器的ABI。)



性状




  • 交换

  • is_aggregate

  • has_unique_object_representations



已过时




  • 一些C库,

  • <codecvt>

  • memory_order_consume

  • result_of,替换为invoke_result

  • shared_ptr::unique,它并非线程安全



自C ++ 14以来,Isocpp.org有一个独立的变化列表;它被部分掠夺。[241] [242] [243] [244] [245] [246] [247] [248] [249]]] [250] [251] [252] [253] [254] [255] [256] [257] [258] [259]]] [260] [261] [262] [263] [264] [265] [266] [267]


自然地,TS工作并行继续,因此有一些TS不够成熟,必须等待下一次迭代。下一次迭代的目标是先前计划的C ++ 20,而不是C ++ 19,正如一些谣言所暗示的那样。已避免使用C ++ 1O。


从reddit帖子和这个reddit帖子中获取的初始列表,通过谷歌搜索或从上面的isocpp.org页面添加链接。[268] [269]


从SD-6特征测试列表中掠夺的其他条目。[270]


clang的功能列表和库功能列表接下来都会被掠夺。这似乎不可靠,因为它是C ++ 1z,而不是C ++ 17。[271] [272]


这些幻灯片在其他地方缺少一些功能。[273]


虽然没有问删除了什么,但这里有一些简短的列表,列出了C ++ 17中从C ++中删除的一些东西((主要是?)以前弃用的):


移除:




  • register,保留供将来使用的关键字

  • bool b; ++b;

  • 三合字母


    • 如果您仍然需要它们,它们现在是源文件编码的一部分,而不是语言的一部分


  • ios别名

  • auto_ptr,旧<functional>东西,random_shuffle

  • [[li> std::function 中的分配器


有重写。我不确定这些是否对代码有任何影响,或者它们是否只是标准中的清理:[274] [275] [276] [277] [278] [279]]]


尚未整合到上面的论文:




  • P0505R0(constexpr chrono)[280]

  • P0418R2(原子调整)[281]

  • P0512R0(模板参数扣除调整)[282]

  • P0490R0(结构化绑定调整)[283]

  • P0513R0(更改为std::hash)[284]

  • P0502R0(并行例外)[285]

  • P0509R1(更新例外处理限制)[286]

  • P0012R1(使异常规范成为类型系统的一部分)[287]

  • P0510R0(对变种的限制)[288]

  • P0504R0(可选/变种/任何标签)[289]

  • P0497R0(共享ptr调整)[290]

  • P0508R0(结构化绑定节点句柄)[291]

  • P0521R0(共享指针使用次数和唯一更改?)[292]



规格变更:




  • 异常规范和抛出表达式



进一步参考:




  • 按年份分组的论文;并非全部接受[293] [294]

  • https://isocpp.org/files/papers/p0636r0.html [295]



    • 此处应更新为对现有功能的修改。