What are the new features in C++17?
C++17 is now feature complete, so unlikely to experience large changes. Hundreds of proposals were put forward for C++17.
Which of those features were added to C++ in C++17?
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?
Solution 1:
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 anint
-
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]]
onnamespace
s andenum { 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
unlessthrow()
, andthrow()
isnoexcept(true)
.
Cleaner multi-return and flow control
-
Structured bindings
-
Basically, first-class
std::tie
withauto
-
Example: *
const auto [it, inserted] = map.insert( {"foo", bar} );
* Creates variablesit
andinserted
with deduced type from thepair
thatmap::insert
returns. -
Works with tuple/pair-likes &
std::array
s and relatively flat structs -
Actually named structured bindings in standard
-
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.
-
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 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?
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]
-
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
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.
- Saves some
-
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
- Polymorphic allocator, like
-
std::sample
, sampling from a range?
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
-
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 otherunique_ptr
tweaks. -
weak_from_this
and some fixed to shared from this
Other std
datatype improvements:
{}
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 -
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
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
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(breaks ABI of some compilers due to name mangling, removed.)std::less
. -
memory_order_consume
, added language to prefer use ofmemory_order_acquire
Traits
- swap
- is_aggregate
- has_unique_object_representations
Deprecated
- Some C libraries,
<codecvt>
-
result_of
, replaced withinvoke_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.