C++17 Progress in VS 2017 15.5 and 15.6

December 19th, 2017

VS 2017 15.5 is now available for production use, and 15.6 Preview 1 is also available. As usual, here are feature tables for the STL and compiler, plus a detailed list of STL improvements. (You can also read our previous changelog for VS 2017 15.3.) Please note that due to our branch structure and merge timing, features and fixes described below as being in VS 2017 15.6 have been checked in and will be available by the time that it’s ready for production use, but 15.6 Preview 1 contains only a subset of those features and fixes.

STL Feature Status:

Status Std Paper Title Notes missing C++17 P0067R5 Elementary String Conversions patch C++17 P0682R1 Repairing Elementary String Conversions [DR] missing C++17 P0030R1 hypot(x, y, z) missing C++17 P0226R1 Mathematical Special Functions Partial C++17 P0024R2 Parallel Algorithms [parallel] patch C++17 P0336R1 Renaming Parallel Execution Policies patch C++17 P0394R4 Parallel Algorithms Should terminate() For Exceptions patch C++17 P0452R1 Unifying <numeric> Parallel Algorithms patch C++17 P0467R2 Requiring Forward Iterators In Parallel Algorithms patch C++17 P0502R0 Parallel Algorithms Should terminate() For Exceptions, Usually patch C++17 P0518R1 Copying Trivially Copy Constructible Elements In Parallel Algorithms patch C++17 P0523R1 Relaxing Complexity Requirements Of Parallel Algorithms (General) patch C++17 P0574R1 Relaxing Complexity Requirements Of Parallel Algorithms (Specific) patch C++17 P0623R0 Final C++17 Parallel Algorithms Fixes missing C++17 P0218R1 <filesystem> patch C++17 P0219R1 Relative Paths For Filesystem patch C++17 P0317R1 Directory Entry Caching For Filesystem patch C++17 P0392R0 Supporting string_view In Filesystem Paths patch C++17 P0430R2 Supporting Non-POSIX Filesystems patch C++17 P0492R2 Resolving NB Comments For Filesystem VS 2017 15.x C++20 P0777R1 Avoiding Unnecessary decay [decay] [14] VS 2017 15.6 C++17 … <memory_resource> VS 2017 15.6 C++17 P0220R1 Library Fundamentals V1 VS 2017 15.6 C++17 P0337R0 Deleting polymorphic_allocator Assignment Partial 15.6 C++17 P0426R1 constexpr For char_traits [char_traits] Partial 15.6 C++17 P0433R2 Deduction Guides For The STL [guides] VS 2017 15.6 C++17 P0739R0 Improving Class Template Argument Deduction For The STL [DR] VS 2017 15.5 C++17 P0003R5 Removing Dynamic Exception Specifications [rem] VS 2017 15.5 C++17 P0005R4 not_fn() [depr] VS 2017 15.5 C++17 P0033R1 Rewording enable_shared_from_this [14] VS 2017 15.5 C++17 P0083R3 Splicing Maps And Sets VS 2017 15.5 C++17 P0174R2 Deprecating Vestigial Library Parts [depr] VS 2017 15.5 C++17 P0302R1 Removing Allocator Support In std::function [rem] VS 2017 15.5 C++17 P0358R1 Fixes For not_fn() VS 2017 15.5 C++17 P0414R2 shared_ptr<T[]>, shared_ptr<T[N]> [14] VS 2017 15.5 C++17 P0497R0 Fixing shared_ptr For Arrays [14] VS 2017 15.5 C++17 P0508R0 Clarifying insert_return_type VS 2017 15.5 C++17 P0521R0 Deprecating shared_ptr::unique() [depr] VS 2017 15.5 C++17 P0607R0 Inline Variables For The STL VS 2017 15.5 C++17 P0618R0 Deprecating <codecvt> [depr] VS 2017 15.3 C++17 … Boyer-Moore search() VS 2017 15.3 C++17 P0031R0 constexpr For <array> (Again) And <iterator> VS 2017 15.3 C++17 P0040R3 Extending Memory Management Tools VS 2017 15.3 C++17 P0084R2 Emplace Return Type VS 2017 15.3 C++17 P0152R1 atomic::is_always_lock_free VS 2017 15.3 C++17 P0154R1 hardware_destructive_interference_size, etc. VS 2017 15.3 C++17 P0156R2 scoped_lock VS 2017 15.3 C++17 P0253R1 Fixing Searcher Return Types VS 2017 15.3 C++17 P0258R2 has_unique_object_representations [obj_rep] VS 2017 15.3 C++17 P0295R0 gcd(), lcm() VS 2017 15.3 C++17 P0298R3 std::byte [byte] VS 2017 15.3 C++17 P0403R1 UDLs For <string_view> (“meow”sv, etc.) VS 2017 15.3 C++17 P0418R2 atomic compare_exchange memory_order Requirements [14] VS 2017 15.3 C++17 P0435R1 Overhauling common_type [14] VS 2017 15.3 C++17 P0505R0 constexpr For <chrono> (Again) VS 2017 15.3 C++17 P0513R0 Poisoning hash [14] VS 2017 15.3 C++17 P0516R0 Marking shared_future Copying As noexcept [14] VS 2017 15.3 C++17 P0517R0 Constructing future_error From future_errc [14] VS 2017 15.3 C++17 P0548R1 Tweaking common_type And duration [14] VS 2017 15.3 C++17 P0558R1 Resolving atomic<T> Named Base Class Inconsistencies [atomic] [14] VS 2017 15.3 C++17 P0599R1 noexcept hash [14] VS 2017 15.3 C++17 P0604R0 invoke_result, is_invocable, is_nothrow_invocable [depr] VS 2017 C++17 … <algorithm> sample() VS 2017 C++17 … <any> VS 2017 C++17 … <optional> VS 2017 C++17 … <string_view> VS 2017 C++17 … <tuple> apply() VS 2017 C++17 P0032R3 Homogeneous Interface For variant/any/optional VS 2017 C++17 P0077R2 is_callable, is_nothrow_callable VS 2017 C++17 P0088R3 <variant> VS 2017 C++17 P0163R0 shared_ptr::weak_type VS 2017 C++17 P0209R2 make_from_tuple() VS 2017 C++17 P0254R2 Integrating string_view And std::string VS 2017 C++17 P0307R2 Making Optional Greater Equal Again VS 2017 C++17 P0393R3 Making Variant Greater Equal VS 2017 C++17 P0504R0 Revisiting in_place_t/in_place_type_t<T>/in_place_index_t<I> VS 2017 C++17 P0510R0 Rejecting variants Of Nothing, Arrays, References, And Incomplete Types VS 2015.3 C++17 P0025R1 clamp() VS 2015.3 C++17 P0185R1 is_swappable, is_nothrow_swappable VS 2015.3 C++17 P0272R1 Non-const basic_string::data() VS 2015.2 C++17 N4387 Improving pair And tuple [14] VS 2015.2 C++17 N4508 shared_mutex (Untimed) [14] VS 2015.2 C++17 P0004R1 Removing Deprecated Iostreams Aliases [rem] VS 2015.2 C++17 P0006R0 Variable Templates For Type Traits (is_same_v, etc.) [14] VS 2015.2 C++17 P0007R1 as_const() [14] VS 2015.2 C++17 P0013R1 Logical Operator Type Traits (conjunction, etc.) [14] VS 2015.2 C++17 P0074R0 owner_less<> [14] VS 2015.2 C++17 P0092R1 <chrono> floor(), ceil(), round(), abs() [14] VS 2015.2 C++17 P0156R0 Variadic lock_guard [14] VS 2015 C++17 N3911 void_t [14] VS 2015 C++17 N4089 Safe Conversions In unique_ptr<T[]> [14] VS 2015 C++17 N4169 invoke() [14] VS 2015 C++17 N4190 Removing auto_ptr, random_shuffle(), And Old <functional> Stuff [rem] VS 2015 C++17 N4258 noexcept Cleanups [14] VS 2015 C++17 N4259 uncaught_exceptions() [14] VS 2015 C++17 N4277 Trivially Copyable reference_wrapper [14] VS 2015 C++17 N4279 insert_or_assign()/try_emplace() For map/unordered_map [14] VS 2015 C++17 N4280 size(), empty(), data() [14] VS 2015 C++17 N4366 Precisely Constraining unique_ptr Assignment [14] VS 2015 C++17 N4389 bool_constant [14] VS 2015 C++17 P0063R3 C11 Standard Library [C11] [14] VS 2013 C++17 N4510 Supporting Incomplete Types In vector/list/forward_list [14]

“…”: For clarity, the Library Fundamentals V1 paper has been decomposed into its individual features, marked by “…” here. The <memory_resource> header will be available in VS 2017 15.6, completing this paper.

missing vs. patch: To give you a better idea of our status, unimplemented papers are marked “missing” for primary features, or “patch” for papers that merely fixed parts of a primary feature. We implement them together, so the large number of “patch” rows doesn’t really indicate a large amount of missing work.

N/A: For clarity, this table has omitted a number of papers that are Not Applicable (nothing for implementers to do, or users to take advantage of), such as wording clarifications.

[14]: These C++17 features are implemented unconditionally, even in /std:c++14 mode (the default). For some features, this was because they predated the introduction of MSVC’s Standard mode options. For other features, conditional implementation would be nearly pointless or undesirably complicated.

[atomic]: This was almost completely implemented in VS 2017 15.3, and the remaining differences are difficult to observe (some signatures differ from the Standard, as observed by taking their address or providing explicit template arguments). The STL’s next major binary-incompatible version will fix the remaining differences.

[byte]: std::byte is enabled by /std:c++17, but has a fine-grained opt-out macro (_HAS_STD_BYTE can be defined to be 0). This is because given certain patterns of using-directives, it can conflict with the Windows SDK’s headers. This has been reported to the SDK team and will be fixed, but in the meantime the escape hatch is available.

[C11]: First available in VS 2015, the Universal CRT implemented the parts of the C11 Standard Library that are required by C++17, with minor exceptions. Those exceptions (which are tracked by bugs) are: missing C99 strftime() E/O alternative conversion specifiers, missing C11 fopen() exclusive mode, and missing C11 aligned_alloc(). The strftime() and fopen() functionality will be implemented in the future. aligned_alloc() will probably never be implemented, as C11 specified it in a way that’s incompatible with our implementation (namely, that free() must be able to handle highly aligned allocations).

[char_traits]: This will be partially available in VS 2017 15.6. The library changes have been implemented and tested, but they’re currently enabled for only the Clang and EDG compiler front-ends (which have implemented the compiler builtins that power this feature). When C1XX (MSVC’s compiler front-end) implements these builtins, we’ll mark this feature as complete.

[decay]: This paper is technically N/A, as it doesn’t require implementers to take action, and it doesn’t result in an observable feature for users. However, it improves compiler throughput, so we’ve gone ahead and implemented it unconditionally (as an exception to “C++17 before C++20”). This will ship in a VS 2017 update after 15.6 (denoted by “15.x” here).

[depr] and [rem]: See See C++17 Feature Removals And Deprecations

[DR]: These papers were voted into the Working Paper after C++17, but as Defect Reports, meaning that they retroactively apply to C++17 (as bugfixes).

[guides]: This will be partially available in VS 2017 15.6. The library changes have been implemented and tested, but they’re currently enabled for Clang only. (Testing MSVC’s STL with Clang found two compiler bugs, This will be partially available in VS 2017 15.6. The library changes have been implemented and tested, but they’re currently enabled for Clang only. (Testing MSVC’s STL with Clang found two compiler bugs, LLVM#34970 and LLVM#35045 . We implemented a workaround for the former, which has been fixed for Clang 6. The latter appears to be extremely obscure and unlikely to be encountered by ordinary code.) When C1XX and EDG implement class template argument deduction, we’ll mark this feature as complete.

[obj_rep]: This type trait (powered by a compiler builtin) is currently enabled for C1XX only. The builtin was recently implemented in Clang, so when Clang 6 is released, we plan to enable the type trait for it. The type trait is also not yet enabled for EDG (which implemented the builtin earlier, but was affected by a compiler bug until recently).

[parallel]: We’re gradually implementing experimental support for the parallel algorithms.

Here are the parallel algorithms that we’ve implemented:

15.5, intentionally not parallelized: copy, copy_n, fill, fill_n, move, reverse, reverse_copy, rotate, rotate_copy, swap_ranges. (The signatures for these parallel algorithms are added but not parallelized at this time; profiling showed no benefit in parallelizing algorithms that only move or permute elements.)

15.5: all_of, any_of, for_each, for_each_n, none_of, reduce, replace, replace_if, sort.

15.6 Preview 1: adjacent_find, count, count_if, equal, find, find_end, find_first_of, find_if, find_if_not.

15.6 after Preview 1: mismatch, remove, remove_if, search, search_n, transform.

15.x: partition, stable_sort.

Compiler Feature Status:

C++03/11/14 Core Language Features Status Paper Notes [Everything else] VS 2017 [throw()] Two-phase name lookup Partial [twoPhase] Expression SFINAE Partial N2634 [exprSFINAE] C99 preprocessor Partial N1653 [preprocessor] C++17 Core Language Features Status Paper Notes Removing trigraphs VS 2010 N4086 [14] New rules for auto with braced-init-lists VS 2015 N3922 [14] typename in template template-parameters VS 2015 N4051 [14] Attributes for namespaces and enumerators VS 2015 N4266 [14] u8 character literals VS 2015 N4267 [14] Ignoring unrecognized attributes VS 2015 P0283R2 [14] Nested namespace definitions VS 2015.3 N4230 Terse static_assert VS 2017 N3928 Generalized range-based for-loops VS 2017 P0184R0 [14] [[fallthrough]] attribute VS 2017 P0188R1 Removing the register keyword VS 2017 15.3 P0001R1 Removing operator++ for bool VS 2017 15.3 P0002R1 Capturing *this by value VS 2017 15.3 P0018R3 Using attribute namespaces without repetition VS 2017 15.3 P0028R4 __has_include VS 2017 15.3 P0061R1 [14] Direct-list-init of fixed enums from integers VS 2017 15.3 P0138R2 constexpr lambdas VS 2017 15.3 P0170R1 [[nodiscard]] attribute VS 2017 15.3 P0189R1 [[maybe_unused]] attribute VS 2017 15.3 P0212R1 Structured bindings VS 2017 15.3 P0217R3 constexpr if-statements VS 2017 15.3 P0292R2 [ifConstexpr] Selection statements with initializers VS 2017 15.3 P0305R1 Allowing more non-type template args VS 2017 15.5 N4268 Fold expressions VS 2017 15.5 N4295 and P0036R0 Removing dynamic-exception-specifications VS 2017 15.5 P0003R5 Adding noexcept to the type system VS 2017 15.5 P0012R1 Over-aligned dynamic memory allocation VS 2017 15.5 P0035R4 Hexfloat literals VS 2017 15.5 P0245R1 Inline variables VS 2017 15.5 P0386R2 Matching template template-parameters to compatible arguments VS 2017 15.5 P0522R0 Guaranteed copy elision VS 2017 15.6 P0135R1 Fixing qualification conversions No N4261 Extended aggregate initialization No P0017R1 Class template argument deduction No P0091R3 and P0512R0 Declaring non-type template parameters with auto No P0127R2 Rewording inheriting constructors No P0136R1 std::launder() No P0137R1 [launder] Refining expression evaluation order No P0145R3 and P0400R0 Pack expansions in using-declarations No P0195R2 Simplifying implicit lambda capture No P0588R1 [DR] Fixing class template argument deduction for initializer-list ctors No P0702R1 [DR] CWG 1581: When are constexpr member functions defined? No P0859R0 [DR]

[throw()]: In /std:c++14 mode, dynamic exception specifications remain unimplemented, and throw() is still treated as a synonym for __declspec(nothrow). In C++17, dynamic exception specifications were mostly removed by In /std:c++14 mode, dynamic exception specifications remain unimplemented, and throw() is still treated as a synonym for __declspec(nothrow). In C++17, dynamic exception specifications were mostly removed by P0003R5 , leaving one vestige: throw() is deprecated and required to behave as a synonym for noexcept. In /std:c++17 mode, MSVC now conforms to the Standard by giving throw() the same behavior as noexcept, i.e. enforcement via termination. The compiler option /Zc:noexceptTypes- requests our old behavior of __declspec(nothrow). It’s likely that throw() will be removed in C++20. To help with migrating code in response to these changes in the Standard and our implementation, new compiler warnings for exception specification issues have been added under /std:c++17 and /permissive- as documented here

[twoPhase]: Two-phase name lookup is partially implemented in VS 2017 15.5 and 15.6, with an increasing number of scenarios working. Please read Two-phase name lookup is partially implemented in VS 2017 15.5 and 15.6, with an increasing number of scenarios working. Please read our Sept 2017 post for more details. The compiler front-end team is monitoring progress via approximately 85 test cases taken from in-house and external test suites and real codebases, with approximately 68% of them passing as of Dec 2017.

[exprSFINAE]: Expression SFINAE has been partially implemented in VS 2017 RTM through 15.6. While many scenarios work (and it has been sufficient for the STL’s purposes for 2 years), some parts are still missing and some workarounds are still required, like the “unique tag type” workaround. As the Parse Tree Rejuvenation effort progresses forward, we’ll be able to support dependent name binding inside decltype expressions, which will help us complete Expression SFINAE. This completion will require the /permissive- mode as it will depend on two-phase name lookup.

[preprocessor]: Support for C99’s preprocessor rules is unchanged (considered partial due to support for variadic macros, although there are numerous bugs). We’re overhauling the preprocessor, and we’ll experimentally ship those changes under the /permissive- mode soon.

[ifConstexpr]: “if constexpr” is supported in /std:c++14 with a warning that can be suppressed, delighting template metaprogramming library authors everywhere.

[launder]: std::launder(), which is 99.9% compiler magic, is currently listed in the compiler feature table, although we may move it to the library feature table in the future.

STL Fixes:

The following fixes are available in VS 2017 15.5, unless otherwise specified as appearing in VS 2017 15.6.

Significant Changes:

The STL is now tested with Clang/LLVM 5.0.0 (in our internal test suites and libc++’s test suite) and no longer supports Clang/C2 3.8.

The STL now identifies itself with two macros, defined by including any STL header (e.g. <ciso646>). _MSVC_STL_VERSION is defined as 141 and will remain that way for the VS 2017 v141 toolset series. _MSVC_STL_UPDATE is defined as 201709 in VS 2017 15.5, and will be increased as features are added in future updates. (The year-month typically won’t correspond to an update’s release date. Our process for updating this macro is “we’re checking in std::meow() and it’s now October, so we need to change the value”, and depending on branch/merge timing, it might take a month or more to ship.) The value for VS 2017 15.6 is not yet set in stone, but it will be 201711 or greater.

New Warnings And Errors:

Including <execution> now emits “warning STL4019: Parallel algorithms support is experimental in this release of Visual C++. Object files and static libraries that include <execution> may need to be rebuilt to link with a future update of Visual C++, and programs using <execution> may not run on Windows XP. This warning will be removed when parallel algorithms support is completed in a future update. You can define _SILENCE_PARALLEL_ALGORITHMS_EXPERIMENTAL_WARNING to acknowledge that you have received this warning.”

(15.6) Added a compiler/STL version mismatch check (with an escape hatch, _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH). Our STL is tested with the corresponding version of C1XX, and they’re treated as a unit by the IDE. (That is, selecting an older toolset will use an older C1XX and a correspondingly older STL.) Our STL is also tested with the latest released version of Clang/LLVM. Mixing an older STL with a newer compiler is untested and unsupported, but will typically work. (For example, using Clang 6 with VS 2017 15.5.) However, because the STL’s implementation is constantly evolving to consume freshly-implemented compiler features and bugfixes, mixing a newer STL with an older compiler is a recipe for doom. By adding a version mismatch check, we can emit a comprehensible error message when imminent doom is detected. Currently, we check C1XX’s version with “#if _MSC_VER < 1912” and emit “#error STL1001: Unexpected compiler version, expected MSVC 19.12.” We also check Clang’s version with “#if __clang_major__ < 5” and emit “#error STL1000: Unexpected compiler version, expected Clang 5.” (We currently don’t check EDG’s version, or that of any other front-ends.) In the future, we will regularly increase the versions being checked here. (For subtle reasons, the lower bound for C1XX’s version being checked here may not always correspond to the version number that it’s actually shipping with. For example, VS 2017 RTM (15.0) was compiler version 19.10, VS 2017 15.3 was 19.11, VS 2017 15.5 was 19.12, and VS 2017 15.6 will be 19.13. While 15.6’s STL is shipping with and being tested with the 19.13 compiler, its version mismatch check will accept 19.12. This is because a checked-in copy of the toolset is used to build the shipping toolset, and at the time that 15.6 branched for release, the checked-in toolset was still identifying itself as 19.12. We might clarify the error message in the future by adding “or newer”.)

(15.6) The [[nodiscard]] attribute has been applied to nearly 2,500 functions in the STL. In /std:c++17 mode, this will emit a compiler warning when the return value of a function is being discarded instead of stored or inspected. (The warning can be portably and locally suppressed by casting to void.) We’ve carefully chosen which functions to mark with [[nodiscard]], so that the warnings will be valuable instead of noisy. Our criteria for emitting the warning are: discarding the return value is a guaranteed leak (e.g. std::allocator::allocate(), but not unique_ptr::release() – this was a judgement call), discarding the return value is near-guaranteed to be incorrect (e.g. remove()/remove_if()/unique()), or the function is essentially a pure observer (e.g. vector::empty() and std::is_sorted()). If you encounter these [[nodiscard]] warnings, we believe it’s highly likely that your code contains a bug, so please think about it instead of reflexively suppressing the warning because it previously compiled cleanly. For example, confusion between vector’s empty() (an observer returning bool) and clear() (an action returning void) is common among beginning programmers, and will be detected by this warning. Even in our own compiler’s codebase, we encountered a case where an array was being given to is_sorted() and then the returned bool was discarded; the intention was to assert that the array was sorted.

Correctness Fixes:

random_device::entropy() is now marked as const.

map/multimap::value_compare’s constructor is now protected, following the Standard.

Increased conformance by avoiding a non-Standard compiler extension (in-class explicit specializations) within the iostreams implementation.

The STL now adapts to whether the compiler provides C++17’s behavior for noexcept (e.g. is_function detects noexcept-qualified function types). The STL also avoids throw().

is_partitioned() was incorrectly calling the predicate N + 1 times, instead of N times as required by the Standard.

atomic<T> no longer requires T to be default constructible.

basic_string::npos is now available as a compile time constant.

std::allocator now properly handles allocation of over-aligned types (whose alignment is greater than max_align_t) in C++17 mode (unless disabled by /Zc:alignedNew-). For example, vectors of objects with 16 or 32-byte alignment will now be properly aligned for SSE/AVX instructions.

shared_ptr’s constructors now handle nullptrs with custom deleters, and unique_ptrs with fancy pointers and custom deleters.

Fixed a bug in scoped_allocator_adaptor::select_on_container_copy_construction() with 3+ allocators.

We constrained std::function’s converting constructor/assignment to avoid competing with copy/move construction/assignment. This avoids bizarre compiler errors in certain situations.

(15.6) Fixed a regression that was introduced in VS 2017 15.5, where compiling with /clr and including STL headers within #pragma managed(push, off) (contrary to the documentation’s guidance ) started emitting compiler errors. We now tolerate this scenario again, while still avoiding the extremely fragile non-Standard extension __if_exists.

(15.6) ratio_less now avoids integer overflow with extreme inputs.

(15.6) sort() now uses difference_type instead of size_t. Other algorithms now respect difference_types that aren’t ptrdiff_t.

(15.6) Fixed a regression that was introduced in VS 2017 15.5, where including <numeric> with /fp:except emitted a compiler error.

(15.6) The STL now supports over-aligned temporary buffers, and therefore supports algorithms on ranges of over-aligned types.

Performance/Throughput Fixes:

Improved the performance of forward_list::empty() in debug mode.

Heap algorithms that take logarithmic time no longer do a linear time assertion that the input is in fact a heap in debug mode.

basic_string now engages memcmp()/memcpy()/etc. optimizations that basic_string engages. Note that constexpr char_traits in VS 2017 15.6 partially reverts this work due to compiler limitations; see LLVM#35165 for more info.

An optimizer limitation (which prevented function pointers from being inlined) that was exposed by our “avoid copying function objects” work in VS 2015.3 has been worked around, restoring the performance of lower_bound(iter, iter, function pointer).

The overhead of iterator debugging’s order verification of inputs to includes(), set_difference(), set_symmetric_difference(), and set_union() was reduced by unwrapping iterators before checking order.

inplace_merge() now skips over elements that are already in position.

Constructing random_device no longer constructs and then destroys a std::string.

equal() and partition() received a jump-threading optimization pass which saves an iterator comparison.

When reverse() is given pointers to trivially copyable T, it will now dispatch to a handwritten vectorized implementation. This can increase performance by up to 8x (times, not percent).

fill(), equal(), and lexicographical_compare() were taught how to dispatch to memset()/memcmp() for std::byte and gsl::byte (and other char-ish enums and enum classes). Note that copy() dispatches using is_trivially_copyable and thus didn’t need any changes.

The STL no longer contains empty-braces destructors whose only behavior was to make types non-trivially-destructible.

Slightly improved codegen size for dual-range, non-random-access equal().

(15.6) Significantly improved compiler throughput when including <ppltasks.h>, which is included by our implementation of <future>.

(15.6) Significantly improved the performance of find_end().

(15.6) Improved the performance of dual-range mismatch() for random-access iterators.

(15.6) Improved the performance of search() by calling memcmp() when possible.

(15.6) Improved the performance of string/string_view’s find_first_of() family by using bitmaps.

Readability And Other Improvements:

The STL now uses variable templates internally.

__declspec(allocator) is now guarded for C1XX only, to prevent warnings from Clang which doesn’t understand this declspec.

The STL now tolerates /Zc:threadSafeInit- which disables magic statics. (We attempted to tolerate this compiler option in VS 2017 15.3, but the attempt was incomplete.)

We dramatically improved the experience of debugging into a std::function call. See our Nov 2017 post for more info. Note that this triggers LLVM#31944 (a Clang bug with PCHes) which has been fixed in Clang 6.

The STL works with “Just My Code” in the debugger again.

In release mode, marked forward_list’s default/move constructors as noexcept.

(15.6) Strengthened noexcept on the constructors and assignment operators of containers and container adaptors to reflect their implementations.

C++20:

We’re working on finishing C++17 before starting C++20. For completeness, here are the rest of the papers that have been voted into the C++20 Working Paper. (While we’ve added many [[nodiscard]] attributes to our codebase, P0600R1 is not yet complete.)

Status Std Paper Title Notes missing C++20 P0020R6 atomic<float>, atomic<double>, atomic<long double> missing C++20 P0053R7 <syncstream> missing C++20 P0202R3 constexpr For <algorithm> And exchange() missing C++20 P0415R1 constexpr For <complex> (Again) missing C++20 P0439R0 enum class memory_order missing C++20 P0457R2 starts_with()/ends_with() For basic_string/basic_string_view missing C++20 P0463R1 endian missing C++20 P0550R2 remove_cvref missing C++20 P0600R1 [[nodiscard]] For The STL, Part 1 [nodiscard] missing C++20 P0616R0 Using move() In <numeric> missing C++20 P0653R2 to_address() missing C++20 P0674R1 make_shared() For Arrays missing C++20 P0718R2 atomic<shared_ptr<T>>, atomic<weak_ptr<T>> [depr] missing C++20 P0767R1 Deprecating is_pod [depr] missing C++20 P0768R1 Library Support For The Spaceship Comparison Operator <=> [depr]

C++20 Core Language Features Status Paper Notes Adding __VA_OPT__ for comma omission and comma deletion No P0306R4 Allowing lambdas in unevaluated contexts No P0315R4 Designated initialization No P0329R4 Allowing lambda-capture [=, this] No P0409R2 Familiar template syntax for generic lambdas No P0428R2 Three-way (spaceship) comparison operator <=> No P0515R3 Range-based for-loops with initializers No P0614R1 Default constructible and assignable stateless lambdas No P0624R2 CWG 1331: const mismatch with defaulted copy constructor No P0641R2 Default member initializers for bit-fields No P0683R1 Relaxing access checking on specializations No P0692R1 Fixing const lvalue ref-qualified pointers to members No P0704R1 Concepts No P0734R0 ADL and function templates that are not visible No P0846R0 Fixing functionality gaps in constraints No P0857R0

Reporting Bugs:

Please let us know what you think about VS 2017 15.5 and 15.6. You can report bugs via the IDE’s Report A Problem and also via the web: go to the VS Developer Community and click on the C++ tab. For compiler and library bugs, it’s important to provide self-contained test cases.

Happy holidays from your C++ Standard Library implementers (and the rest of the Visual C++ team!):