{"id":19485151,"url":"https://github.com/fenbf/cpp17features","last_synced_at":"2026-03-03T00:41:07.826Z","repository":{"id":38708579,"uuid":"78366139","full_name":"fenbf/cpp17features","owner":"fenbf","description":"C++ features jump start","archived":false,"fork":false,"pushed_at":"2022-10-14T12:18:05.000Z","size":97,"stargazers_count":122,"open_issues_count":0,"forks_count":17,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-02-25T18:38:45.356Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fenbf.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-08T19:39:34.000Z","updated_at":"2024-07-28T16:31:09.000Z","dependencies_parsed_at":"2023-01-19T18:45:55.949Z","dependency_job_id":null,"html_url":"https://github.com/fenbf/cpp17features","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fenbf/cpp17features","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fenbf%2Fcpp17features","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fenbf%2Fcpp17features/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fenbf%2Fcpp17features/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fenbf%2Fcpp17features/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fenbf","download_url":"https://codeload.github.com/fenbf/cpp17features/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fenbf%2Fcpp17features/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30027740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T00:31:48.536Z","status":"ssl_error","status_checked_at":"2026-03-03T00:30:56.176Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T20:26:03.251Z","updated_at":"2026-03-03T00:41:07.794Z","avatar_url":"https://github.com/fenbf.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# All Major C++17 Features You Should Know\n\nThe ISO Committee accepted and published the C++17 Standard in December 2017. In this mega-long article, I’ve built (with your help!) a list of **all major features** of the new standard.\n\nPlease have a look and see what we get!\n\n-   [Language Features](#language-features)\n    -   [New auto rules for direct-list-initialization](#new-auto-rules-for-direct-list-initialization)\n    -   [static\\_assert with no message](#staticassert-with-no-message)\n    -   [typename in a template template parameter](#typename-in-a-template-template-parameter)\n    -   [Removing trigraphs](#removing-trigraphs)\n    -   [Nested namespace definition](#nested-namespace-definition)\n    -   [Attributes for namespaces and enumerators](#attributes-for-namespaces-and-enumerators)\n    -   [u8 character literals](#u8-character-literals)\n    -   [Allow constant evaluation for all non-type template  arguments](#allow-constant-evaluation-for-all-non-type-template-arguments)\n    -   [Fold Expressions](#fold-expressions)\n    -   [Unary fold expressions and empty parameter packs](#unary-fold-expressions-and-empty-parameter-packs)\n    -   [Remove Deprecated Use of the register Keyword](#remove-deprecated-use-of-the-register-keyword)\n    -   [Remove Deprecated operator++(bool)](#remove-deprecated-operatorbool)\n    -   [Removing Deprecated Exception Specifications from C++17](#removing-deprecated-exception-specifications-from-c17)\n    -   [Make exception specifications part of the type system](#make-exception-specifications-part-of-the-type-system)\n    -   [Aggregate initialization of classes with base classes](#aggregate-initialization-of-classes-with-base-classes)\n    -   [Lambda capture of \\*this](#lambda-capture-of-this)\n    -   [Using attribute namespaces without repetition](#using-attribute-namespaces-without-repetition)\n    -   [Dynamic memory allocation for over-aligned data](#dynamic-memory-allocation-for-over-aligned-data)\n    -   [\\_\\_has\\_include in preprocessor conditionals](#hasinclude-in-preprocessor-conditionals)\n    -   [Template argument deduction for class templates](#template-argument-deduction-for-class-templates)\n    -   [Non-type template parameters with auto type](#non-type-template-parameters-with-auto-type)\n    -   [Guaranteed copy elision](#guaranteed-copy-elision)\n    -   [New specification for inheriting constructors (DR1941 et al)](#new-specification-for-inheriting-constructors-dr1941-et-al)\n    -   [Direct-list-initialization of enumerations](#direct-list-initialization-of-enumerations)\n    -   [Stricter expression evaluation order](#stricter-expression-evaluation-order)\n    -   [constexpr lambda expressions](#constexpr-lambda-expressions)\n    -   [Different begin and end types in range-based for](#different-begin-and-end-types-in-range-based-for)\n    -   [\\[\\[fallthrough\\]\\] attribute](#fallthrough-attribute)\n    -   [\\[\\[nodiscard\\]\\] attribute](#nodiscard-attribute)\n    -   [\\[\\[maybe\\_unused\\]\\] attribute](#maybeunused-attribute)\n    -   [Ignore unknown attributes](#ignore-unknown-attributes)\n    -   [Pack expansions in using-declarations](#pack-expansions-in-using-declarations)\n    -   [Structured Binding Declarations](#structured-binding-declarations)\n    -   [Hexadecimal floating-point literals](#hexadecimal-floating-point-literals)\n    -   [init-statements for if and switch](#init-statements-for-if-and-switch)\n    -   [Inline variables](#inline-variables)\n    -   [DR: Matching of template template-arguments excludes compatible templates](#dr-matching-of-template-template-arguments-excludes-compatible-templates)\n    -   [`std::uncaught_exceptions()`](#stduncaughtexceptions)\n    -   [constexpr if-statements](#constexpr-if-statements)\n        -   [SFINAE](#sfinae)\n        -   [Tag dispatching](#tag-dispatching)\n        -   [if constexpr](#if-constexpr)\n-   [Library Features](#library-features)\n    -   [Merged: The Library Fundamentals 1 TS (most parts)](#merged-the-library-fundamentals-1-ts-most-parts)\n    -   [Removal of some deprecated types and functions, including std::auto\\_ptr, std::random\\_shuffle, and old function adaptors](#removal-of-some-deprecated-types-and-functions-including-stdautoptr-stdrandomshuffle-and-old-function-adaptors)\n    -   [Merged: The Parallelism TS, a.k.a. “Parallel STL.”,](#merged-the-parallelism-ts-aka-parallel-stl)\n    -   [Merged: File System TS,](#merged-file-system-ts)\n    -   [Merged: The Mathematical Special Functions IS,](#merged-the-mathematical-special-functions-is)\n    -   [Improving std::pair and std::tuple](#improving-stdpair-and-stdtuple)\n    -   [std::shared\\_mutex (untimed)](#stdsharedmutex-untimed)\n    -   [Variant](#variant)\n    -   [Splicing Maps and Sets](#splicing-maps-and-sets)\n    -   [Elementary string conversion](#elementary-string-conversion)\n    -   [`std::apply`](#stdapply)\n    -   [`std::invoke`](#stdinvoke)\n-   [Contributors](#contributors)\n-   [Summary](#summary)\n\nIntro\n-----\n\n**Updated**: This post was updated on 10th October 2022.\n\nIf you have code examples, better explanations or any ideas, let me know! I am happy to update the current post so that it has some real value for others.\n\nThe plan is to have a list of features with some basic explanation, little example (if possible) and some additional resources, plus a note about availability in compilers. Probably, most of the features might require separate articles or even whole chapters in books, so the list here will be only a jump start.\n\n**See this** GitHub repo: [github/fenbf/cpp17features](https://github.com/fenbf/cpp17features). Add a pull request to update the content.\n\nThe feature list comes from the following resources:\n\n-   [SO: What are the new features in C++17?](http://stackoverflow.com/questions/38060436/what-are-the-new-features-in-c17)\n-   [cppreference.com/C++ compiler support](http://en.cppreference.com/w/cpp/compiler_support).\n-   [AnthonyCalandra/modern-cpp-features cheat sheet](https://github.com/AnthonyCalandra/modern-cpp-features) - unfortunately it doesn’t include all the features of C++17.\n-   plus other findings and mentions\n\nAnd one of the most important resource: [N4659, 2017-03-21, **Draft, Standard for Programming Language C++**](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf) - from [isocpp.org](https://isocpp.org/).\n\nPlus, there’s an official list of changes: [P0636r0: Changes between C++14 and C++17 DIS](https://isocpp.org/files/papers/p0636r0.html)\n\nAlso, you can grab my list of concise descriptions of all of the C++17 - It’s a one-page reference card:\n\nI also have a more detailed series:\n\n1.  [Fixes and deprecation](https://www.cppstories.com/2017/05/cpp17-details-fixes-deprecation.html)\n2.  [Language clarification](https://www.cppstories.com/2017/06/cpp17-details-clarifications.html)\n3.  [Templates](https://www.cppstories.com/2017/06/cpp17-details-templates.htm)\n4.  [Attributes](https://www.cppstories.com/2017/07/cpp17-in-details-attributes.html)\n5.  [Simplification](https://www.cppstories.com/2017/07/cpp17-details-simplifications.html)\n6.  [Library changes - Filesystem](https://www.cppstories.com/2017/08/cpp17-details-filesystem.html)\n7.  [Library changes - Parallel\n    STL](https://www.cppstories.com/2017/08/cpp17-details-parallel.html)\n8.  [Library changes - Utils](https://www.cppstories.com/2017/09/cpp17-details-utils.html)\n9.  [Wrap up, Bonus](https://www.cppstories.com/2017/09/c17-in-detail-summary-bonus.html) -\n    with a free ebook! :)\n\nAnd another cool article: \n\n* [17 Smaller but Handy C++17 Features - C++ Stories](https://www.cppstories.com/2019/08/17smallercpp17features/)\n\n[![](../../images/2017-01-09-c-17-features-cpp17indetail.png)](https://leanpub.com/cpp17indetail)\n\nResources about C++17 STL:\n\n-   [**C++17 In Detail**](https://leanpub.com/cpp17) by Bartek!\n\n## Language Features\n\n### New auto rules for direct-list-initialization\n\n[N3922](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 5.0\u003c/th\u003e\n\u003cth\u003eClang: 3.8\u003c/th\u003e\n\u003cth\u003eMSVC: 14.0\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nFixes some cases with auto type deduction. The full background can be found in [Auto and braced-init-lists](http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3681.html), by Ville Voutilainen.\n\nIt fixes the problem of deducing `std::initializer_list` like:\n\n```cpp\nauto x = foo(); // copy-initialization\nauto x{foo}; // direct-initialization, initializes an initializer_list\nint x = foo(); // copy-initialization\nint x{foo}; // direct-initialization\n```\n\nAnd for the direct initialization, new rules are:\n\n-   For a braced-init-list with only a single element, auto deduction will deduce from that entry;\n-   For a braced-init-list with more than one element, auto deduction will be ill-formed.\n\nBasically, `auto x { 1 };` will be now deduced as `int`, but before it was an initializer list.\n\n### `static_assert` with no message\n\n[N3928](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3928.pdf)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 2.5\u003c/th\u003e\n\u003cth\u003eMSVC: 15.0 preview 5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nSelf-explanatory. It allows having the condition without passing the message, version with the message will also be available. It will be compatible with other asserts like `BOOST_STATIC_ASSERT` (that didn’t take any message from the start).\n\n### `typename` in a `template template` parameter\n\n[N4051](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 5.0\u003c/th\u003e\n\u003cth\u003eClang: 3.5\u003c/th\u003e\n\u003cth\u003eMSVC: 14.0\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nAllows you to use `typename` instead of `class` when declaring a template template parameter. Normal type parameters can use them interchangeably, but template template parameters were restricted to `class`, so this change unifies these forms somewhat.\n\n```cpp\ntemplate \u003ctemplate \u003ctypename...\u003e typename Container\u003e\n//            used to be invalid ^^^^^^^^\nstruct foo;\n\nfoo\u003cstd::vector\u003e my_foo;\n```    \n\n### Removing trigraphs\n\n[N4086](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4086.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 5.1\u003c/th\u003e\n\u003cth\u003eClang: 3.5\u003c/th\u003e\n\u003cth\u003eMSVC: Yes\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nRemoves `??=`, `??(`, `??\u003e`, ...\n\nMakes the implementation a bit simpler, see [MSDN Trigraphs](https://msdn.microsoft.com/en-us/library/bt0y4awe.aspx)\n\n### Nested namespace definition\n\n[N4230](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4230.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 3.6\u003c/th\u003e\n\u003cth\u003eMSVC: 14.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nAllows writing:\n\n```cpp\nnamespace A::B::C {\n   // ...\n}\n```\n\nRather than:\n\n```cpp\nnamespace A {\n    namespace B {\n        namespace C {\n            // ...\n        }\n    }\n}\n```\n\n### Attributes for namespaces and enumerators\n\n[N4266](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4266.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 4.9 (namespaces)/ 6 (enums)\u003c/th\u003e\n\u003cth\u003eClang: 3.4\u003c/th\u003e\n\u003cth\u003eMSVC: 14.0\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nPermits attributes on enumerators and namespaces. More details in [N4196](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4196.html).\n\n```cpp\nenum E {\n  foobar = 0,\n  foobat [[deprecated]] = foobar\n};\n\nE e = foobat; // Emits warning\n\nnamespace [[deprecated]] old_stuff{\n    void legacy();\n}\n\nold_stuff::legacy(); // Emits warning\n```    \n\n### `u8` character literals\n\n[N4267](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4267.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 3.6\u003c/th\u003e\n\u003cth\u003eMSVC: 14.0\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\n\u003e UTF-8 character literal, e.g. `u8'a'`. Such literal has type `char` and the value equal to ISO 10646 code point value of c-char, provided that the code point value is representable with a single UTF-8 code unit. If c-char is not in Basic Latin or C0 Controls Unicode block, the program is ill-formed.\n\nThe compiler will report errors if a character cannot fit inside `u8` ASCII range.\n\nReference:\n\n-   [cppreference.com/character literal](http://en.cppreference.com/w/cpp/language/character_literal)\n-   [SO: What is the point of the UTF-8 character literals proposed for C++17?](http://stackoverflow.com/questions/31970111/what-is-the-point-of-the-utf-8-character-literals-proposed-for-c17)\n\n### Allow constant evaluation for all non-type template arguments\n\n[N4268](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 3.6\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nRemove syntactic restrictions for pointers, references, and pointers to members that appear as non-type template parameters:\n\nFor instance:\n\n```cpp\ntemplate\u003cint *p\u003e struct A {};\nint n;\nA\u003c\u0026n\u003e a; // ok\n\nconstexpr int *p() { return \u0026n; }\nA\u003cp()\u003e b; // error before C++17\n```    \n\n### Fold Expressions\n\n[N4295](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4295.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 3.6\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nMore background here in [P0036](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0036r0.pdf)\n\nAllows writing compact code with variadic templates without using explicit recursion.\n\nExample:\n\n```cpp\ntemplate\u003ctypename... Args\u003e\nauto SumWithOne(Args... args){\n    return (1 + ... + args);\n}\n```    \n\nArticles:\n\n-   [Bartek’s coding blog: C++17 in details: Templates](https://www.cppstories.com/2017/06/cpp17-details-templates.html#fold-expressions)\n-   [C++ Truths: Folding Monadic Functions](http://cpptruths.blogspot.com/2017/01/folding-monadic-functions.html)\n-   [Simon Brand: Exploding tuples with fold expressions](https://tartanllama.github.io/c++/2016/11/10/exploding-tuples-fold-expressions/)\n-   [Baptiste Wicht: C++17 Fold Expressions](http://baptiste-wicht.com/posts/2015/05/cpp17-fold-expressions.html)\n-   [Fold Expressions - ModernesCpp.com](http://www.modernescpp.com/index.php/fold-expressions)\n\n### Unary fold expressions and empty parameter packs\n\n[P0036R0](http://wg21.link/p0036r0)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nIf the parameter pack is empty then the value of the fold is:\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth style=\"text-align: right;\"\u003eOperator\u003c/th\u003e\n\u003cth\u003eValue\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr class=\"odd\"\u003e\n\u003ctd style=\"text-align: right;\"\u003e\u0026amp;\u0026amp;\u003c/td\u003e\n\u003ctd\u003etrue\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr class=\"even\"\u003e\n\u003ctd style=\"text-align: right;\"\u003e||\u003c/td\u003e\n\u003ctd\u003efalse\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr class=\"odd\"\u003e\n\u003ctd style=\"text-align: right;\"\u003e,\u003c/td\u003e\n\u003ctd\u003evoid()\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nFor any operator not listed above, an unary fold expression with an empty parameter pack is ill-formed.\n\n### Remove Deprecated Use of the `register` Keyword\n\n[P0001R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0001r1.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.8\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nThe `register` keyword was deprecated in the 2011 C++ standard. C++17 tries to clear the standard, so the keyword is now removed. This keyword is reserved now and might be repurposed in future revisions.\n\n### Remove Deprecated `operator++(bool)`\n\n[P0002R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0002r1.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.8\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nThe `++operator` for `bool` was deprecated in the original 1998 C++ standard, and it is past time to remove it formally.\n\n### Removing Deprecated Exception Specifications from C++17\n\n[P0003R5](http://wg21.link/p0003r5)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.0\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nDynamic exception specifications were deprecated in C++11. This paper formally proposes removing the feature from C++17, while retaining the (still) deprecated `throw()` specification strictly as an alias for `noexcept(true)`.\n\n### Make exception specifications part of the type system\n\n[P0012R1](http://wg21.link/p0012r1)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nPreviously exception specifications for a function didn’t belong to the type of the function, but it will be part of it.\n\nWe’ll get an error in the case:\n\n```cpp\nvoid (*p)();\nvoid (**pp)() noexcept = \u0026p;   // error: cannot convert to pointer to noexcept function\n\nstruct S { typedef void (*p)(); operator p(); };\nvoid (*q)() noexcept = S();   // error: cannot convert to pointer to noexcept function\n```\n\n### Aggregate initialization of classes with base classes\n\n[P0017R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.7\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nIf a class was derived from some other type you couldn’t use aggregate initialization. But now the restriction is removed.\n\n```cpp\nstruct base { int a1, a2; };\nstruct derived : base { int b1; };\n\nderived d1{{1, 2}, 3};      // full explicit initialization\nderived d1{{}, 1};          // the base is value initialized\n```\n\nTo sum up: from the standard:\n\n\u003e An aggregate is an array or a class with:  \n\u003e \\* no user-provided constructors (including those inherited from a\n\u003e base class),  \n\u003e \\* no private or protected non-static data members (Clause 11),  \n\u003e \\* no base classes (Clause 10) and // removed now!  \n\u003e \\* no virtual functions (10.3), and  \n\u003e \\* no virtual, private or protected base classes (10.1).\n\nSee more in [Five tricky topics for data members in C++20 - C++ Stories](https://www.cppstories.com/2022/five-topics-data-members-cpp20/#1-changing-status-of-aggregates) - \"Changing status of aggregates\"\n\n### Lambda capture of `*this`\n\n[P0018R3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0018r3.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\n`this` pointer is implicitly captured by lambdas inside member functions (if you use a default capture, like `[\u0026]` or `[=]`). Member variables are always accessed by this pointer.\n\nExample:\n\n```cpp\nstruct S {\n   int x ;\n   void f() {\n      // The following lambda captures are currently identical\n      auto a = [\u0026]() { x = 42 ; } // OK: transformed to (*this).x\n      auto b = [=]() { x = 43 ; } // OK: transformed to (*this).x\n      a();\n      assert( x == 42 );\n      b();\n      assert( x == 43 );\n   }\n};\n```\n\nNow you can use `*this` when declaring a lambda, for example `auto b = [=, *this]() { x = 43 ; }`. That way `this` is captured by value. Note that the form `[\u0026,this]` is redundant but accepted for compatibility with ISO C++14.\n\nCapturing by value might be especially important for async invocation, paraller processing.\n\nSee more at [C++ Lambdas, Threads, std::async and Parallel Algorithms - C++ Stories](https://www.cppstories.com/2020/05/lambdas-async.html/#capturing-this)\n\n### Using attribute namespaces without repetition\n\n[P0028R4](http://wg21.link/p0028r4)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nOther name for this feature was “Using non-standard attributes” in [P0028R3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0028r3.html) and [PDF: P0028R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0028r2.pdf) (rationale, examples).\n\nSimplifies the case where you want to use multiple attributes, like:\n\n```cpp\nvoid f() {\n    [[rpr::kernel, rpr::target(cpu,gpu)]] // repetition\n    do-task();\n}\n```\n\nProposed change:\n\n```cpp\nvoid f() {\n    [[using rpr: kernel, target(cpu,gpu)]]\n    do-task();\n}\n```\n\nThat simplification might help when building tools that automatically translate annotated such code into a different programming models.\n\n### Dynamic memory allocation for over-aligned data\n\n[P0035R4](http://wg21.link/p0035r4)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nIn the following example:\n\n```cpp\nclass alignas(16) float4 {\n    float f[4];\n};\nfloat4 *p = new float4[1000];\n```\n\nC++11/14 did not specify any mechanism by which over-aligned data can be dynamically allocated correctly (i.e. respecting the alignment of the data). In the example above, not only is an implementation of C++ not required to allocate properly-aligned memory for the array, for practical purposes it is very nearly required to do the allocation incorrectly.\n\nC++17 fixes that hole by introducing additional memory allocation functions that use align parameter:\n\n```cpp\nvoid* operator new(std::size_t, std::align_val_t);\nvoid* operator new[](std::size_t, std::align_val_t);\nvoid operator delete(void*, std::align_val_t);\nvoid operator delete[](void*, std::align_val_t);\nvoid operator delete(void*, std::size_t, std::align_val_t);\nvoid operator delete[](void*, std::size_t, std::align_val_t);\n```\n\nSee more in [New new() - The C++17's Alignment Parameter for Operator new() - C++ Stories](https://www.cppstories.com/2019/08/newnew-align/).\n\n### `__has_include` in preprocessor conditionals\n\n[P0061R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0061r1.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 5.0\u003c/th\u003e\n\u003cth\u003eClang: yes\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nThis feature allows a C++ program to directly, reliably and portably determine whether or not a library header is available for inclusion.\n\nExample: This demonstrates a way to use a library optional facility only if it is available.\n\n```cpp\n#if __has_include(\u003coptional\u003e)\n#  include \u003coptional\u003e\n#  define have_optional 1\n#elif __has_include(\u003cexperimental/optional\u003e)\n#  include \u003cexperimental/optional\u003e\n#  define have_optional 1\n#  define experimental_optional 1\n#else\n#  define have_optional 0\n#endif\n```\n\n### Template argument deduction for class templates\n\n[P0091R3](http://wg21.link/p0091r3)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 5\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.7\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nBefore C++17, template deduction worked for functions but not for classes. For instance, the following code was legal:\n\n```cpp\nvoid f(std::pair\u003cint, char\u003e);\n\nf(std::make_pair(42, 'z'));\n```\n\nbecause `std::make_pair` is a *template function* (so we can perform template deduction). But the following wasn’t:\n\n```cpp\nvoid f(std::pair\u003cint, char\u003e);\n\nf(std::pair(42, 'z'));\n```\n\nAlthough it is semantically equivalent. This was not legal because `std::pair` is a *template class*, and template classes could not apply type deduction in their initialization.\n\nSo before C++17 one has to write out the types explicitly, even though this does not add any new information:\n\n```cpp\nvoid f(std::pair\u003cint, char\u003e);\n\nf(std::pair\u003cint, char\u003e(42, 'z'));\n```\n\nThis is fixed in C++17 where template class constructors can deduce type parameters. The syntax for constructing such template classes is therefore consistent with the syntax for constructing non-template classes.\n\nSee more in:\n\n-   [Bartek’s coding blog: C++17 in details: Templates](https://www.cppstories.com/2017/06/cpp17-details-templates.html#template-argument-deduction-for-class-templates)\n-   [A 4 min episode of C++ Weekly on class template argument type deduction](https://www.youtube.com/watch?v=dEBQL4KPSk8)\n-   [A 4 min episode of C++ Weekly on deduction guides](https://www.youtube.com/watch?v=-3fVp0U4xi0)\n-   [Modern C++ Features - Class Template Argument Deduction -](https://arne-mertz.de/2017/06/class-template-argument-deduction/)\n-   [Deducing your intentions | Andrzej's C++ blog](https://akrzemi1.wordpress.com/2018/12/09/deducing-your-intentions/)\n-   [\\_Contra\\_ CTAD – Arthur O'Dwyer – Stuff mostly about C++](https://quuxplusone.github.io/blog/2018/12/09/wctad/)\n\n### Non-type template parameters with auto type\n\n[P0127R2](http://wg21.link/p0127r2)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.7\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nAutomatically deduce type on non-type template parameters.\n\n```cpp\ntemplate \u003cauto value\u003e void f() { }\nf\u003c10\u003e();               // deduces int\n```\n\n[Trip report: Summer ISO C++ standards meeting (Oulu) | Sutter’s\nMill](https://herbsutter.com/2016/06/30/trip-report-summer-iso-c-standards-meeting-oulu/)\n\n### Guaranteed copy elision\n\n[P0135R1](http://wg21.link/p0135r1)\n\nCopy elision for temporary objects, not for Named RVO.\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.6\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\n```cpp\n// based on P0135R0\nstruct NonMoveable \n{\n  NonMoveable(int);\n  // no copy or move constructor:\n  NonMoveable(const NonMoveable\u0026) = delete;\n  NonMoveable(NonMoveable\u0026\u0026) = delete;\n\n  std::array\u003cint, 1024\u003e arr;\n};\n\nNonMoveable make() \n{\n  return NonMoveable(42);\n}\n\n// construct the object:\nauto largeNonMovableObj = make();\n```\n\nArticles:\n\n-   [Bartek’s coding blog: C++17 in details: language clarifications](https://www.cppstories.com/2017/06/cpp17-details-clarifications.html#guaranteed-copy-elision)\n-   [Jonas Devlieghere: Guaranteed Copy Elision](https://jonasdevlieghere.com/guaranteed-copy-elision/)\n-  [Guaranteed Copy Elision Does Not Elide Copies - C++ Team Blog](https://devblogs.microsoft.com/cppblog/guaranteed-copy-elision-does-not-elide-copies/)\n\n### New specification for inheriting constructors (DR1941 et al)\n\n[P0136R1](http://wg21.link/p0136r1)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.7\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nMore description and reasoning in [P0136R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r0.html). Some excerpts below:\n\n\u003e An inheriting constructor does not act like any other form of using-declaration. All other using-declarations make some set of declarations visible to name lookup in another context, but an inheriting constructor declaration declares a new constructor that merely delegates to the original.\n\nThis feature changes inheriting constructor declaration from declaring a set of new constructors, to making a set of base class constructors visible in a derived class as if they were derived class constructors. (When such a constructor is used, the additional derived class subobjects will also be implicitly constructed as if by a defaulted default constructor). Put another way: make inheriting a constructor act just like inheriting any other base class member, to the extent\npossible.\n\nThis change does affect the meaning and validity of some programs, but these changes improve the consistency and comprehensibility of C++.\n\n```cpp\n// Hiding works the same as for other member\n// using-declarations in the presence of default arguments\nstruct A {\n  A(int a, int b = 0);\n  void f(int a, int b = 0);\n};\nstruct B : A {\n  B(int a);      using A::A;\n  void f(int a); using A::f;\n};\nstruct C : A {\n  C(int a, int b = 0);      using A::A;\n  void f(int a, int b = 0); using A::f;\n};\n\nB b(0); // was ok, now ambiguous\nb.f(0); // ambiguous (unchanged)\n\nC c(0); // was ambiguous, now ok\nc.f(0); // ok (unchanged)\n\n// Inheriting constructor parameters are no longer copied\nstruct A { A(const A\u0026) = delete; A(int); };\nstruct B { B(A); void f(A); };\nstruct C : B { using B::B; using B::f; };\nC c({0}); // was ill-formed, now ok (no copy made)\nc.f({0}); // ok (unchanged)\n```\n\n### Direct-list-initialization of enumerations\n\n[P0138R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0138r2.pdf)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nAllows the initialization of an enum class with a fixed underlying type:\n\n```cpp\nenum class Handle : uint32_t { Invalid = 0 };\nHandle h { 42 }; // OK\n```\n\nAllows creating `strong types` that are easy to use...\n\n### Stricter expression evaluation order\n\n[P0145R3](http://wg21.link/p0145r3)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.7\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nIn a nutshell, given an expression such as `f(a, b, c)`, the order in which the sub-expressions f, a, b, c (which are of arbitrary shapes) are evaluated is left unspecified by the standard.\n\n```cpp\n// unspecified behaviour below!\nf(i++, i);\n\nv[i] = i++;\n\nstd::map\u003cint, int\u003e m;\nm[0] = m.size(); // {{0, 0}} or {{0, 1}} ?\n```\n\nSummary of changes:\n\n-   Postfix expressions are evaluated from left to right. This includes functions calls and member selection expressions.\n-   Assignment expressions are evaluated from right to left. This includes compound assignments.\n-   Operands to shift operators are evaluated from left to right.\n\nSee more in: [Stricter Expression Evaluation Order in C++17 - C++ Stories](https://www.cppstories.com/2021/evaluation-order-cpp17/)\n\nReference:\n\n-   [Bartek’s coding blog: C++17 in details: language clarifications](https://www.cppstories.com/2017/06/cpp17-details-clarifications.html#stricter-expression-evaluation-order)\n-   [C++ Order of evaluation, cppreference](http://en.cppreference.com/w/cpp/language/eval_order)\n-   [SO: What are the evaluation order guarantees introduced by C++17?](http://stackoverflow.com/questions/38501587/what-are-the-evaluation-order-guarantees-introduced-by-c17)\n-   [How compact code can become buggy code: getting caught by the order of evaluations, Fluent C++](http://www.fluentcpp.com/2017/05/09/compact-code-becomes-buggy-code-order-evaluations/)\n\n### `constexpr` lambda expressions\n\n[P0170R1](http://wg21.link/p0170r1)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 5\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\n`constexpr` can be used in the context of lambdas.\n\n```cpp\nconstexpr auto ID = [] (int n)  { return n; };\nconstexpr int I = ID(3);\nstatic_assert(I == 3);\n\nconstexpr int AddEleven(int n) {\n  // Initialization of the 'data member' for n can\n  // occur within a constant expression since 'n' is\n  // of literal type.\n  return [n] { return n + 11; }();\n}\nstatic_assert(AddEleven(5) == 16);\n```\n\nArticles\n\n-   [A 5 min episode of Jason Turner’s C++ Weekly about constexpr lambdas](https://www.youtube.com/watch?v=kmza9U_niq4)\n-   [Lambda expression comparison between C++11, C++14 and C++17](https://maitesin.github.io/Lambda_comparison/)\n\n### Different begin and end types in range-based for\n\n[P0184R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 3.6\u003c/th\u003e\n\u003cth\u003eMSVC: 15.0 Preview 5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nChanging the definition of range based for from:\n\n```cpp\n{\n   auto \u0026\u0026 __range = for-range-initializer;\n   for ( auto __begin = begin-expr,\n              __end = end-expr;\n              __begin != __end;\n              ++__begin ) {\n        for-range-declaration = *__begin;\n        statement\n   }\n}\n```    \n\nInto:\n\n```cpp\n{\n  auto \u0026\u0026 __range = for-range-initializer;\n  auto __begin = begin-expr;\n  auto __end = end-expr;\n  for ( ; __begin != __end; ++__begin ) {\n    for-range-declaration = *__begin;\n    statement\n  }\n}\n```\n\nTypes of `__begin` and `__end` might be different; only the comparison operator is required. This little change allows Range TS users a better experience.\n\n### `[[fallthrough]]` attribute\n\n[P0188R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0188r1.pdf)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.0 Preview 4\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nIndicates that a fallthrough in a switch statement is intentional and a warning should not be issued for it. More details in [P0068R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0068r0.pdf).\n\n```cpp\nswitch (c) {\ncase 'a':\n    f(); // Warning emitted, fallthrough is perhaps a programmer error\ncase 'b':\n    g();\n[[fallthrough]]; // Warning suppressed, fallthrough is intentional\ncase 'c':\n    h();\n}\n```\n\nSee more in [C++17 in details: Attributes - C++ Stories](https://www.cppstories.com/2017/07/cpp17-in-details-attributes/)\n\n### `[[nodiscard]]` attribute\n\n[P0189R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0189r1.pdf)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\n`[[nodiscard]]` is used to stress that the return value of a function is not to be discarded, on pain of a compiler warning. More details in [P0068R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0068r0.pdf).\n\n```cpp\n[[nodiscard]] int foo();\nvoid bar() {\n    foo(); // Warning emitted, return value of a nodiscard function is discarded\n}\n```\n\nThis attribute can also be applied to types in order to mark all functions which return that type as `[[nodiscard]]`:\n\n```cpp\n[[nodiscard]] struct DoNotThrowMeAway{};\nDoNotThrowMeAway i_promise();\nvoid oops() {\n    i_promise(); // Warning emitted, return value of a nodiscard function is discarded\n}\n```\n\nArticles:\n\n-   [Bartek’s coding blog: Enforcing code contracts with \\[\\[nodiscard\\]\\]](https://www.cppstories.com/2017/11/nodiscard.html)\n-   [A 4 min video about nodiscard in Jason Turner’s C++ Weekly](https://www.youtube.com/watch?v=l_5PF3GQLKc)\n\n### `[[maybe_unused]]` attribute\n\n[P0212R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0212r1.pdf)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nSuppresses compiler warnings about unused entities when they are declared with `[[maybe_unused]]`. More details in [P0068R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0068r0.pdf).\n\n```cpp\n                 static void impl1() { ... } // Compilers may warn about this\n[[maybe_unused]] static void impl2() { ... } // Warning suppressed\n\nvoid foo() {\n                      int x = 42; // Compilers may warn about this\n     [[maybe_unused]] int y = 42; // Warning suppressed\n}\n```\n\n[A 3 min video about maybe\\_unused in Jason Turner’s C++ Weekly](https://www.youtube.com/watch?v=WSPmNL9834U)\n\n### Ignore unknown attributes\n\n[P0283R2](http://wg21.link/p0283r2)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: Yes\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nClarifies that implementations should ignore any attribute namespaces which they do not support, as this used to be unspecified. More details in [P0283R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0283r1.pdf).\n\n```cpp\n//compilers which don't support MyCompilerSpecificNamespace will ignore this attribute\n[[MyCompilerSpecificNamespace::do_special_thing]]\nvoid foo();\n```\n\n### Pack expansions in using-declarations\n\n[P0195R2](http://wg21.link/p0195r2)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.7\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nAllows you to inject names with *using-declarations* from all types in a parameter pack.\n\nIn order to expose `operator()` from all base classes in a variadic template, we used to have to resort to recursion:\n\n```cpp\ntemplate \u003ctypename T, typename... Ts\u003e\nstruct Overloader : T, Overloader\u003cTs...\u003e {\n    using T::operator();\n    using Overloader\u003cTs...\u003e::operator();\n    // […]\n};\n\ntemplate \u003ctypename T\u003e struct Overloader\u003cT\u003e : T {\n    using T::operator();\n};\n```\n\nNow we can simply expand the parameter pack in the *using-declaration*:\n\n```cpp\ntemplate \u003ctypename... Ts\u003e\nstruct Overloader : Ts... {\n    using Ts::operator()...;\n    // […]\n};\n```\n\nSee more in [2 Lines Of Code and 3 C++17 Features - The overload Pattern - C++ Stories](https://www.cppstories.com/2019/02/2lines3featuresoverload.html/)\n\nRemarks\n\n-   Implemented in GCC 7.0, see [this change](https://github.com/gcc-mirror/gcc/commit/caba101ff33a763b444090b9c073bd84972ee552).\n\n### Structured Binding Declarations\n\n[P0217R3](http://wg21.link/p0217r3)  \n[P0615R0: Renaming for structured\nbindings](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0615r0.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nHelps when using tuples as a return type. It will automatically create variables and `tie` them. More details in [P0144R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0144r0.pdf).\n\nThe name “Decomposition Declaration” was also used, but finally the standard agrees to use “Structured Binding Declarations” (section 11.5)\n\nFor example:\n\n```cpp\nint a = 0;\ndouble b = 0.0;\nlong c = 0;\nstd::tie(a, b, c) = tuple; // a, b, c need to be declared first\n```\n\nNow we can write:\n\n```cpp\nauto [ a, b, c ] = tuple;\n```\n\nSuch expressions also work on structs, pairs, and arrays.\n\nArticles:\n\n-   [Steve Lorimer, C++17 Structured Bindings](https://skebanga.github.io/structured-bindings/)\n-   [jrb-programming, Emulating C++17 Structured Bindings in C++14](http://jrb-programming.blogspot.fr/2016/02/emulating-c17-structured-binding-in-c14.html)\n-   [Simon Brand, Adding C++17 decomposition declaration support to your classes](https://tartanllama.github.io/c++/2016/07/20/structured-bindings/)\n\n### Hexadecimal floating-point literals\n\n[P0245R1](http://wg21.link/p0245r1)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 3.0\u003c/th\u003e\n\u003cth\u003eClang: Yes\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.3t\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nAllows expressing some special floating point values, for example, the smallest normal IEEE-754 single precision value is readily written as `0x1.0p-126`.\n\n### init-statements for if and switch\n\n[P0305R1](http://wg21.link/p0305r1)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nNew versions of the if and switch statements for C++:\n\n`if (init; condition)` and `switch (init; condition)`.\n\nThis should simplify the code. For example, previously you had to write:\n\n```cpp\n{\n    auto val = GetValue();\n    if (condition(val))\n        // on success\n    else\n        // on false...\n}\n```\n\nLook, that `val` has a separate scope, without it it will ‘leak’.\n\nNow you can write:\n\n```cpp\nif (auto val = GetValue(); condition(val))\n    // on success\nelse\n    // on false...\n```\n\n`val` is visible only inside the `if` and `else` statements, so it doesn’t ‘leak’. `condition` might be any condition, not only if `val` is true/false.\n\nExamples:\n\n-   [C++ Weekly - Ep 21 C++17’s `if` and `switch` Init Statements](https://www.youtube.com/watch?v=AiXU5EuLZgc\u0026feature=youtu.be)\n\n### Inline variables\n\n[P0386R2](http://wg21.link/p0386r2)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nPreviously only methods/functions could be specified as `inline`, now you can do the same with variables, inside a header file.\n\n\u003e A variable declared inline has the same semantics as a function declared inline: it can be defined, identically, in multiple translation units, must be defined in every translation unit in which it is used, and the behavior of the program is as if there is exactly one variable.\n\n```cpp\nstruct MyClass\n{\n    static const int sValue;\n};\n\ninline int const MyClass::sValue = 777;\n```\n\nOr even:\n\n```cpp\nstruct MyClass\n{\n    inline static const int sValue = 777;\n};\n```\n\nArticles\n\n-   [17 Smaller but Handy C++17 Features - C++ Stories](https://www.cppstories.com/2019/08/17smallercpp17features/#2-inline-variables) - inline variables\n-   [SO: What is an inline variable and what is it useful for?](http://stackoverflow.com/questions/38043442/what-is-an-inline-variable-and-what-is-it-useful-for)\n\n### DR: Matching of template template-arguments excludes compatible templates\n\n[P0522R0](http://wg21.link/p0522r0)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 4.0\u003c/th\u003e\n\u003cth\u003eMSVC: VS 2017 15.5\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nThis feature resolves [Core issue CWG 150](http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4457.html#150).\n\nFrom the paper:\n\n\u003e This paper allows a template template-parameter to bind to a template argument whenever the template parameter is at least as specialized as the template argument. This implies that any template argument list that can legitimately be applied to the template template-parameter is also applicable to the argument template.\n\nExample:\n\n```cpp\ntemplate \u003ctemplate \u003cint\u003e class\u003e void FI();\ntemplate \u003ctemplate \u003cauto\u003e class\u003e void FA();\ntemplate \u003cauto\u003e struct SA { /* ... */ };\ntemplate \u003cint\u003e struct SI { /* ... */ };\nFI\u003cSA\u003e();  // OK; error before this paper\nFA\u003cSI\u003e();  // error\n\ntemplate \u003ctemplate \u003ctypename\u003e class\u003e void FD();\ntemplate \u003ctypename, typename = int\u003e struct SD { /* ... */ };\nFD\u003cSD\u003e();  // OK; error before this paper (CWG 150)\n```\n\n(Adapted from the [comment](https://www.reddit.com/r/cpp/comments/5osck2/c_17_features/dcm7eq4/) by [IncongruentModulo1](https://www.reddit.com/user/IncongruentModulo1)) \n\nFor a useful example, consider something like this:\n\n```cpp\ntemplate \u003ctemplate \u003ctypename\u003e typename Container\u003e\nstruct A\n{\n    Container\u003cint\u003e    m_ints;\n    Container\u003cdouble\u003e m_doubles;\n};\n```\n\nIn C++14 and earlier, `A\u003cstd::vector\u003e` wouldn’t be valid (ignoring the typename and not class before container) since `std::vector` is declared as:\n\n`template \u003ctypename T, typename Allocator = std::allocator\u003cT\u003e\u003e class vector;`\n\nThis change resolves that issue. Before, you would need to declare template `\u003ctemplate \u003ctypename...\u003e typename Container\u003e`, which is more permissive and moves the error to a less explicit line (namely the declaration of `m_ints` wherever the `struct A` is implemented /declared, instead of where the struct is instantiated with the wrong template type.\n\n### `std::uncaught_exceptions()`\n\n[N4259](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4259)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 6.0\u003c/th\u003e\n\u003cth\u003eClang: 3.7\u003c/th\u003e\n\u003cth\u003eMSVC: 14.0\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nMore background in the original paper: [PDF: N4152](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152) and [GOTW issue 47: Uncaught Exceptions](http://www.gotw.ca/gotw/047.htm).\n\nThe function returns the number of uncaught exception objects in the current thread.\n\nThis might be useful when implementing proper Scope Guards that works also during stack unwinding.\n\n\u003e A type that wants to know whether its destructor is being run to unwind this object can query uncaught\\_exceptions  in its constructor and store the result, then query uncaught\\_exceptions again in its destructor; if the result is different,  then this destructor is being invoked as part of stack unwinding due to a new exception that was thrown later than the object’s construction\n\nThe above quote comes from [PDF: N4152](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152).\n\n### `constexpr` if-statements\n\n[P0292R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r2.html)\n\n{{\u003crawhtml\u003e}}\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr class=\"header\"\u003e\n\u003cth\u003eGCC: 7.0\u003c/th\u003e\n\u003cth\u003eClang: 3.9\u003c/th\u003e\n\u003cth\u003eMSVC: 15.3\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e{{\u003c/rawhtml\u003e}}\n\nThe static-if for C++! This allows you to discard branches of an if statement at compile-time based on a constant expression condition.\n\n```cpp\nif constexpr(cond)\n     statement1; // Discarded if cond is false\nelse\n     statement2; // Discarded if cond is true\n```\n\nThis removes a lot of the necessity for tag dispatching and SFINAE:\n\n#### SFINAE\n\n```cpp\ntemplate \u003ctypename T, std::enable_if_t\u003cstd::is_arithmetic\u003cT\u003e{}\u003e* = nullptr\u003e\nauto get_value(T t) {/*...*/}\n\ntemplate \u003ctypename T, std::enable_if_t\u003c!std::is_arithmetic\u003cT\u003e{}\u003e* = nullptr\u003e\nauto get_value(T t) {/*...*/}\n```\n\n#### Tag dispatching\n\n```cpp\ntemplate \u003ctypename T\u003e\nauto get_value(T t, std::true_type) {/*...*/}\n\ntemplate \u003ctypename T\u003e\nauto get_value(T t, std::false_type) {/*...*/}\n\ntemplate \u003ctypename T\u003e\nauto get_value(T t) {\n    return get_value(t, std::is_arithmetic\u003cT\u003e{});\n}\n```\n\n#### if constexpr\n\n```cpp\ntemplate \u003ctypename T\u003e\nauto get_value(T t) {\n     if constexpr (std::is_arithmetic_v\u003cT\u003e) {\n         //...\n     }\n     else {\n         //...\n     }\n}\n```\n\nArticles:\n\n-   [Bartek’s coding blog: Simplify code with ‘if constexpr’ in C++17](https://www.cppstories.com/2018/03/ifconstexpr.html)\n-   [LoopPerfect Blog, C++17 vs C++14 - Round 1 - if-constexpr](https://medium.com/@LoopPerfect/c-17-vs-c-14-if-constexpr-b518982bb1e2)\n-   [SO: constexpr if and `static_assert`](http://stackoverflow.com/questions/38304847/constexpr-if-and-static-assert)\n-   [Simon Brand: Simplifying templates and \\#ifdefs with if constexpr](https://tartanllama.github.io/c++/2016/12/12/if-constexpr/)\n\nLibrary Features\n----------------\n\nTo get more details about library implementation I suggest those links:\n\n-   [VS 2015 Update 2’s STL is C++17-so-far Feature Complete](https://blogs.msdn.microsoft.com/vcblog/2016/01/22/vs-2015-update-2s-stl-is-c17-so-far-feature-complete/) - Jan 2016\n-   [libstdc++, C++ 201z status](https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.201z)\n-   [libc++ C++1z Status](http://libcxx.llvm.org/cxx1z_status.html)\n\nThis section only mentions some of the most important parts of library changes, it would be too impractical to go into details of every little change.\n\n### Merged: The Library Fundamentals 1 TS (most parts)\n\n[P0220R1](https://isocpp.org/files/papers/p0220r1.html)\n\nWe get the following items:\n\n-   Tuples - [Calling a function with a tuple of arguments](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#tuple.apply)\n-   Functional Objects - [Searchers](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#func.searchers)\n-   [Optional objects](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#optional) - `std::optional`!\n-   [Class any](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#any) - `std::any`!\n-   [`std::string_view`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#string.view)\n-   Memory:  \n    -   [Shared-ownership pointers](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.smartptr)\n    -   [Class memory_resource](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource)\n    -   [Access to program-wide memory\\_resource objects](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource.global)\n    -   [Pool resource classes](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource.pool)\n    -   [Class monotonic\\_buffer\\_resource](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource.monotonic.buffer)\n    -   [Alias templates using polymorphic memory\n        resources](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#memory.resource.aliases)\n-   Algorithms:  \n    -   [Search](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#alg.search)\n    -   [Sampling](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#alg.random.sample)\n-   `shared_ptr` natively handles arrays: see [Merging shared\\_ptr  changes from Library Fundamentals to  C++17](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0414r2.html)\n\nThe wording from those components comes from Library Fundamentals V2 to ensure the wording includes the latest corrections.\n\nResources:\n\n- [Using C++17 std::optional - C++ Stories](https://www.cppstories.com/2018/05/using-optional/)\n- [C++Stories: Standard Library Utilities](https://www.cppstories.com/2017/09/cpp17-details-utils.html)\n- [Marco Arena, `string_view` odi et amo](https://marcoarena.wordpress.com/2017/01/03/string_view-odi-et-amo/)\n\n### Removal of some deprecated types and functions, including `std::auto_ptr`, `std::random_shuffle`, and old function adaptors\n\n[N4190](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0001r1.html)\n\n-   Function objects - unary\\_function/binary\\_function, ptr\\_fun(), and  mem\\_fun()/mem\\_fun\\_ref()\n-   Binders - bind1st()/bind2nd()\n-   **auto\\_ptr**\n-   Random shuffle - random\\_shuffle(first, last) and random\\_shuffle(first, last, rng)\n\n### Merged: The Parallelism TS, a.k.a. “Parallel STL.”,\n\n[P0024R2](http://isocpp.org/files/papers/P0024R2.html)\n\nParralel versions/overloads of most of std algorithms. Plus a few new\nalgorithms, like reduce, transform\\_reduce, for\\_each.\n\n```cpp\nstd::vector\u003cint\u003e v = genLargeVector();\n\n// standard sequential sort\nstd::sort(v.begin(), v.end());\n\n// explicitly sequential sort\nstd::sort(std::seq, v.begin(), v.end());\n\n// permitting parallel execution\nstd::sort(std::par, v.begin(), v.end());\n\n// permitting vectorization as well\nstd::sort(std::par_unseq, v.begin(), v.end());\n```\n\nArticles:\n\n-   [Bartek’s coding blog: C++17 in details: Parallel Algorithms](https://www.cppstories.com/2017/08/cpp17-details-parallel.html)\n-   [Parallel Algorithm of the Standard Template Library -  ModernesCpp.com](http://www.modernescpp.com/index.php/parallel-algorithm-of-the-standard-template-library)\n\n### Merged: File System TS,\n\n[P0218R1](https://isocpp.org/files/papers/P0218r1.html)\n\n```cpp\nnamespace fs = std::filesystem;\n\nfs::path pathToShow(/* ... */);\ncout \u003c\u003c \"exists() = \" \u003c\u003c fs::exists(pathToShow) \u003c\u003c \"\\n\"\n     \u003c\u003c \"root_name() = \" \u003c\u003c pathToShow.root_name() \u003c\u003c \"\\n\"\n     \u003c\u003c \"root_path() = \" \u003c\u003c pathToShow.root_path() \u003c\u003c \"\\n\"\n     \u003c\u003c \"relative_path() = \" \u003c\u003c pathToShow.relative_path() \u003c\u003c \"\\n\"\n     \u003c\u003c \"parent_path() = \" \u003c\u003c pathToShow.parent_path() \u003c\u003c \"\\n\"\n     \u003c\u003c \"filename() = \" \u003c\u003c pathToShow.filename() \u003c\u003c \"\\n\"\n     \u003c\u003c \"stem() = \" \u003c\u003c pathToShow.stem() \u003c\u003c \"\\n\"\n     \u003c\u003c \"extension() = \" \u003c\u003c pathToShow.extension() \u003c\u003c \"\\n\";\n```\n\nArticles:\n\n-   [Bartek’s coding blog: C++17 in details:\n    Filesystem](https://www.cppstories.com/2017/08/cpp17-details-filesystem.html)\n\n### Merged: The Mathematical Special Functions IS,\n\n[PDF - WG21 P0226R1](https://isocpp.org/files/papers/P0226R1.pdf)\n\n### Improving [std::pair](http://en.cppreference.com/w/cpp/utility/pair) and [std::tuple](http://en.cppreference.com/w/cpp/utility/tuple)\n\n[N4387](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387.html)\n\n### [`std::shared_mutex`](http://en.cppreference.com/w/cpp/thread/shared_mutex) (untimed)\n\n[N4508](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4508.html)\n\n### `std::variant`\n\n[P0088R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0088r2.html)\n\nVariant is a typesafe union that will report errors when you want to access something that’s not currently inside the object.\n\n```cpp\nstd::variant\u003cstd::string, int\u003e v { \"Hello A Quite Long String\" };\n// v allocates some memory for the string\nv = 10; // we call destructor for the string!\n// no memory leak\n```\n\nNotes:\n\n-   Variant is not allowed to allocate additional (dynamic) memory.\n-   A variant is not permitted to hold references, arrays, or the type `void`.\n-   A variant is default initialized with the value of its first alternative.\n-   If the first alternative type is not default constructible, then the variant must use std::monostate as the first alternative\n\nHave a look at more example in a separate article:  \n\n[Everything You Need to Know About std::variant from C++17 - C++ Stories](https://www.cppstories.com/2018/06/variant/)\n\n### Splicing Maps and Sets\n\n[P0083R2](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r2.pdf)\n\nFrom Herb Sutter, [Oulu trip report](https://herbsutter.com/2016/06/30/trip-report-summer-iso-c-standards-meeting-oulu/):\n\n\u003e You will now be able to directly move internal nodes from one node-based container directly into another container of the same type. Why is that important? Because it guarantees no memory allocation overhead, no copying of keys or values, and even no exceptions if the container’s comparison function doesn’t throw.\n\nNew functions:\n\n* `std::map::extract`\n* `std::map::merge`\n* `std::set::extract`\n* `std::set::merge`\n\n### Elementary string conversion\n\n`from_chars` and `to_chars` which are low-level, and offers the best possible performance\n\nThe new conversion routines are:\n\n* non-throwing\n* non-allocating\n* no locale support\n* memory safety\n* error reporting gives additional information about the conversion outcome\n* bound checked\n* explicit round-trip guarantees - you can use to_chars and from_charsto convert the number back and forth, and it will give you the exact binary representations. This is not guaranteed by other routines like printf/sscanf/itoa, etc.\n\nSimple example:\n\n```cpp\nstd::string str { \"xxxxxxxx\" };\nconst int value = 1986;\nstd::to_chars(str.data(), str.data() + str.size(), value);\n\n// str is \"1986xxxx\"\n```\n\nmore in:\n\n* [How to Use The Newest C++ String Conversion Routines - std::from\\_chars - C++ Stories](https://www.cppstories.com/2018/12/fromchars/)\n* [How to Convert Numbers into Text with std::to\\_chars in C++17 - C++ Stories](https://www.cppstories.com/2019/11/tochars/)\n\n### `std::apply`\n\nA handy helper for `std::tuple`. It takes a tuple and a callable object and then invokes this callable with parameters fetched from the tuple.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003ctuple\u003e\n \nint sum(int a, int b, int c) { \n    return a + b + c; \n}\n\nvoid print(std::string_view a, std::string_view b) {\n    std::cout \u003c\u003c \"(\" \u003c\u003c a \u003c\u003c \", \" \u003c\u003c b \u003c\u003c \")\\n\";\n} \n\nint main() {\n    std::tuple numbers {1, 2, 3};\n    std::cout \u003c\u003c std::apply(sum, numbers) \u003c\u003c '\\n';\n\n    std::tuple strs {\"Hello\", \"World\"};\n    std::apply(print, strs);\n}\n```\n\nSee more in [C++ Templates: How to Iterate through std::tuple: std::apply and More - C++ Stories](https://www.cppstories.com/2022/tuple-iteration-apply/)\n\n### `std::invoke`\n\nWith `std::invoke` you get access to INVOKE expression that was defined in the Standard since C++11 (or even in C++0x, TR1), but wasn’t exposed outside.\n\nIt can handle the following callables:\n\n* function objects: like `func(arguments...)`\n* pointers to member functions `(obj.*funcPtr)(arguments...)`\n* pointer to member data `obj.*pdata`\n\nIn C++20 it was improved and marked with `constexpr`.\n\nSee more in [C++20 Ranges, Projections, std::invoke and if constexpr - C++ Stories](https://www.cppstories.com/2020/10/understanding-invoke.html/)\n\nContributors\n------------\n\nThis is a place for you to be mentioned!\n\nContributors:\n\n-   [Simon Brand](https://tartanllama.github.io/)\n-   [Jonathan Boccara, Fluent{C++}](http://www.fluentcpp.com/)\n-   [Marek Kurdej](https://twitter.com/Kurdej)\n-   suggestions from r/cpp thread:  [`c_17_features`](https://www.reddit.com/r/cpp/comments/5osck2/c_17_features/)\n\nSummary\n-------\n\nThanks for all the support with the list!\n\nThere are still items that should be updated, but the list is mostly done.\n\nIf you want to read more about C++17, have a look at my book\n\n[![](../../images/2017-01-09-c-17-features-cpp17indetail.png)](https://leanpub.com/cpp17indetail/c/fall22)\n\n[C++17 In Detail, -17% coupon code](https://leanpub.com/cpp17indetail/c/fall22)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffenbf%2Fcpp17features","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffenbf%2Fcpp17features","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffenbf%2Fcpp17features/lists"}