Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the new features in C++17?

People also ask

Should I use C++17?

I'd use the C++17 flag by default, it's the default in the latest version of clang too iirc. You should use the latest language features as long as you don't need to support builds on older compilers or embedded platforms that only have outdated compilers, as mentioned above.

When did C++17 come out?

The C++17 specification reached the Draft International Standard (DIS) stage in March 2017. This DIS was unanimously approved, with only editorial comments, and the final standard was published in December 2017.


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/p0433r2 http://wg21.link/p0620r0 http://wg21.link/p0512r0
  • template <auto>

    • Represents a value of any (non-type template argument) type.
  • Non-type template arguments fixes

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

  • ( Folding + ... + expressions ) and Revisions

  • auto x{8}; is an int

  • modernizing using with ... and lists

Lambda

  • constexpr lambdas

    • Lambdas are implicitly constexpr if they qualify
  • Capturing *this in lambdas

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

Attributes

  • [[fallthrough]], [[nodiscard]], [[maybe_unused]] attributes

  • [[attributes]] on namespaces and enum { erator[[s]] }

  • using in attributes to 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.

Syntax cleanup

  • Inline variables

    • Like inline functions
    • Compiler picks where the instance is instantiated
    • Deprecate static constexpr redeclaration, now implicitly inline.
  • namespace A::B

  • Simple static_assert(expression); with no string

  • no throw unless throw(), and throw() is noexcept(true).

Cleaner multi-return and flow control

  • Structured bindings

    • Basically, first-class std::tie with auto
    • Example:
      • const auto [it, inserted] = map.insert( {"foo", bar} );
      • Creates variables it and inserted with deduced type from the pair that map::insert returns.
    • Works with tuple/pair-likes & std::arrays and relatively flat structs
    • Actually named structured bindings in standard
  • if (init; condition) and switch (init; condition)

    • if (const auto [it, inserted] = map.insert( {"foo", bar} ); inserted)
    • Extends the if(decl) to cases where decl 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.
  • if constexpr

    • Much requested feature to simplify almost-generic code.

Misc

  • Hexadecimal float point literals

  • Dynamic memory allocation for over-aligned data

  • Guaranteed copy elision

    • 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) expressions with 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.
  • Direct list-initialization of enums

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

  • "noexcept" in the type system

  • __has_include

    • Test if a header file include would be an error
    • makes migrating from experimental to std almost seamless
  • Arrays of pointer conversion fixes

  • inherited constructors fixes to some corner cases (see P0136R0 for examples of behavior changes)

  • aggregate initialization with inheritance.

  • std::launder, type punning, etc

Library additions:

Data types

  • std::variant<Ts...>

    • Almost-always non-empty last I checked?
    • Tagged union type
    • {awesome|useful}
  • std::optional

    • Maybe holds one of something
    • Ridiculously useful
  • std::any

    • Holds one of anything (that is copyable)
  • std::string_view

    • 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

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 construction

  • 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
    • Deprecates result_of
    • is_invocable<Foo(Args...), R> is "can you call Foo with Args... and get something compatible with R", where R=void is default.
    • invoke_result<Foo, Args...> is std::result_of_t<Foo(Args...)> but apparently less confusing?

File System TS v1

  • [class.path]

  • [class.filesystem.error]

  • [class.file_status]

  • [class.directory_entry]

  • [class.directory_iterator] and [class.recursive_directory_iterator]

  • [fs.ops.funcs]

  • fstreams can be opened with paths, 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

  • Added for threading purposes, exposed even if you aren't using them threaded

Threading

  • std::shared_mutex

    • Untimed, which can be more efficient if you don't need it.
  • atomic<T>::is_always_lockfree

  • scoped_lock<Mutexes...>

    • Saves some std::lock pain when locking more than one mutex at a time.
  • Parallelism TS v1

    • The linked paper from 2014, may be out of date
    • Parallel versions of std algorithms, and related machinery
  • hardware_*_interference_size

(parts of) Library Fundamentals TS v1 not covered above or below

  • [func.searchers] and [alg.search]
    • A searching algorithm and techniques
  • [pmr]

    • 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
  • std::sample, sampling from a range?

Container Improvements

  • try_emplace and insert_or_assign

    • gives better guarantees in some cases where spurious move/copy would be bad
  • Splicing for map<>, unordered_map<>, set<>, and unordered_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
  • Minimal incomplete type support in containers

  • Contiguous iterator "concept"

  • constexpr iterators

  • The emplace family of functions now returns a reference to the created object.

Smart pointer changes

  • unique_ptr<T[]> fixes and other unique_ptr tweaks.
  • weak_from_this and some fixed to shared from this

Other std datatype improvements:

  • {} construction of std::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

  • destroy(_at|_n), uninitialized_move(_n), uninitialized_value_construct(_n), uninitialized_default_construct(_n)

    • utility code already in most std implementations exposed
  • Special math functions
    • scientists may like them
  • std::clamp()
    • std::clamp( a, b, c ) == std::max( b, std::min( a, c ) ) roughly
  • gcd and lcm
  • 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
  • std::chrono polish
  • std::conjunction, std::disjunction, std::negation exposed
  • std::not_fn
    • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0358r1.html
  • 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 std::less. (breaks ABI of some compilers due to name mangling, removed.)

Traits

  • swap
  • is_aggregate
  • has_unique_object_representations

Deprecated

  • Some C libraries,
  • <codecvt>
  • memory_order_consume
  • result_of, replaced with invoke_result
  • shared_ptr::unique, it isn't very threadsafe

Isocpp.org has has an independent list of changes since C++14; it has been partly pillaged.

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.

Initial list taken from this reddit post and this reddit post, with links added via googling or from the above isocpp.org page.

Additional entries pillaged from SD-6 feature-test list.

clang's feature list and library feature list are next to be pillaged. This doesn't seem to be reliable, as it is C++1z, not C++17.

these slides had 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++:

Removed:

  • register, keyword reserved for future use
  • bool 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

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

Spec changes:

  • exception specs and throw expressions

Further reference:

  • papers grouped by year; not all accepted

  • https://isocpp.org/files/papers/p0636r0.html

    • Should be updated to "Modifications to existing features" here.