C++17 Features In Visual Studio 2017 Version 15.3 Preview

May 10th, 2017

Visual Studio 2017 version 15.3 preview is now available, containing an updated Visual C++ toolset (i.e. compiler, linker, and libraries). Like VS 2015’s Updates, we’re adding C++17 features in VS 2017’s Updates, at a similar release frequency. Unlike VS 2015’s Updates (which combined IDE and toolset changes), VS 2017’s IDE is being updated more frequently (with what we’re calling “minor Updates”). That’s why this is the first toolset Update (also called a “foundational Update”).

Here’s the compiler feature table, with some notes. While you can download VS 2017 15.3 preview 1 today, we’ve checked in additional features for Preview 2 which will be released soon. We want to tell you about both sets of features, so features that will be available in Preview 2 (but aren’t available today) are marked as [P2].

C++03/11 Core Language Features Status Paper Notes [Everything else] VS 2015 [A] Two-phase name lookup Partial [twoPhase] Expression SFINAE Partial N2634 [B] C99 preprocessor Partial N1653 [C] Extended integer types N/A N1988 [D] C++14 Core Language Features Status Paper Notes Avoiding/fusing allocations N/A N3664 [E] Tweaked wording for contextual conversions VS 2013 N3323 Binary literals VS 2015 N3472 auto and decltype(auto) return types VS 2015 N3638 init-captures VS 2015 N3648 Generic lambdas VS 2015 N3649 Variable templates VS 2015.2 N3651 Extended constexpr VS 2017 N3652 NSDMIs for aggregates VS 2017 N3653 [[deprecated]] attribute VS 2015 N3760 Sized deallocation VS 2015 N3778 Digit separators VS 2015 N3781 C++17 Core Language Features Status Paper Notes New rules for auto with braced-init-lists VS 2015 N3922 [14] Terse static_assert VS 2017 N3928 typename in template template-parameters VS 2015 N4051 [14] Removing trigraphs VS 2010 N4086 [14] Nested namespace definitions VS 2015.3 N4230 Fixing qualification conversions No N4261 Attributes for namespaces and enumerators VS 2015 N4266 [14] u8 character literals VS 2015 N4267 [14] Allowing more non-type template args No N4268 Fold expressions No N4295 Removing some empty unary folds No P0036R0 Removing the register keyword VS 2017.3 P0001R1 Removing operator++ for bool VS 2017.3 P0002R1 Adding noexcept to the type system No P0012R1 Extended aggregate initialization No P0017R1 Capturing *this by value VS 2017.3 P0018R3 __has_include VS 2017.3 [P2] P0061R1 [14] Rewording inheriting constructors No P0136R1 Direct-list-init of fixed enums from integers VS 2017.3 P0138R2 constexpr lambdas VS 2017.3 P0170R1 Generalized range-based for-loops VS 2017 P0184R0 [14] [[fallthrough]] attribute VS 2017 P0188R1 [[nodiscard]] attribute VS 2017.3 P0189R1 [[maybe_unused]] attribute VS 2017.3 P0212R1 Hexfloat literals No P0245R1 Using attribute namespaces without repetition VS 2017.3 P0028R4 Over-aligned dynamic memory allocation No P0035R4 Template argument deduction for class templates No P0091R3 Declaring non-type template parameters with auto No P0127R2 Guaranteed copy elision VS 2017.3 P0135R1 Refining expression evaluation order No P0145R3 Structured bindings VS 2017.3 P0217R3 Ignoring unrecognized attributes No P0283R2 constexpr if-statements VS 2017.3 [P2] P0292R2 [F] Selection statements with initializers VS 2017.3 [P2] P0305R1 Inline variables No P0386R2 Matching template template-parameters to compatible arguments No P0522R0 Removing dynamic-exception-specifications No P0003R5 Pack expansions in using-declarations No P0195R2

[A] Except for dynamic exception specifications, which were deprecated in C++11 and mostly removed in C++17. Note that C++17 18.4 [except.spec]/2 says “The noexcept-specifier throw() is deprecated (D.3), and equivalent to the noexcept-specifier noexcept(true).” but VS 2017 version 15.3 preview currently considers throw() to be equivalent to __declspec(nothrow).

[twoPhase] While two-phase name lookup isn’t supported in VS 2017 version 15.3 preview, the compiler team is performing major work behind the scenes. For Preview 2, the /permissive- compiler option will activate partial support for two-phase name lookup (partial meaning roughly 60% complete). We’ll publish a detailed blog post in the future. (edited on May 10 at 3:30 PM Pacific Time for accuracy)

[B] Although Expression SFINAE is partially supported, it’s nearly complete. It was sufficient for the STL back in VS 2015.2, and Expression SFINAE has received further bugfixes for additional libraries like Boost. The most significant remaining deficiency is the need to use unique tag types when performing void_t/decltype Expression SFINAE.

[C] C99 preprocessor support is still partial, in that variadic macros mostly work. We’re planning to overhaul the preprocessor before marking this as complete.

[D] Extended integer types are permitted but not required. Like Clang and GCC, we’ve chosen not to implement any.

[E] Avoiding/fusing allocations is permitted but not required. For the time being, we’ve chosen not to implement this.

[F] Supported under /std:c++14 with “warning C4984: ‘if constexpr’ is a C++17 language extension”. This will allow the STL (in the future) to use “if constexpr” within its implementation.

[14] These features are always enabled, even under /std:c++14.

[P2] These features have been checked in and will be available in VS 2017.3 Preview 2.

Here’s the STL feature table:

Status Std Paper Title Notes missing C++17 P0604R0 Changing is_callable/result_of To is_invocable/invoke_result (Options A and B) missing C++17 P0005R4 not_fn() patch C++17 P0358R1 Fixes For not_fn() missing C++17 P0618R0 Deprecating <codecvt> missing C++17 P0521R0 Deprecating shared_ptr::unique() missing C++17 P0174R2 Deprecating Vestigial Library Parts missing C++17 P0003R5 Removing Dynamic Exception Specifications missing C++17 P0302R1 Removing Allocator Support In std::function missing C++17 P0433R2 Deduction Guides For The STL missing C++17 P0607R0 Inline Variables For The STL (Options A and B2) missing C++17 P0258R2 has_unique_object_representations missing C++17 P0426R1 constexpr For char_traits missing C++17 P0063R3 C11 Standard Library missing C++17 P0033R1 Rewording enable_shared_from_this missing C++17 P0414R2 shared_ptr<T[]>, shared_ptr<T[N]> patch C++17 P0497R0 Fixing shared_ptr For Arrays missing C++17 P0083R3 Splicing Maps And Sets patch C++17 P0508R0 Clarifying insert_return_type missing C++17 P0067R5 Elementary String Conversions … C++17 P0220R1 Library Fundamentals V1 missing C++17 … <memory_resource> patch C++17 P0337R0 Deleting polymorphic_allocator Assignment missing C++17 P0030R1 hypot(x, y, z) missing C++17 P0226R1 Mathematical Special Functions missing C++17 P0024R2 Parallel Algorithms [G] 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 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.3 [P2] C++17 P0031R0 constexpr For <array> (Again) And <iterator> VS 2017.3 [P2] C++17 P0084R2 Emplace Return Type VS 2017.3 [P2] C++17 P0295R0 gcd(), lcm() VS 2017.3 [P2] C++17 P0298R3 std::byte [H] VS 2017.3 [P2] C++17 P0435R1 Overhauling common_type [14] VS 2017.3 [P2] C++17 P0505R0 constexpr For <chrono> (Again) VS 2017.3 [P2] C++17 P0548R1 Tweaking common_type And duration [14] VS 2017.3 C++17 … Boyer-Moore search() VS 2017.3 C++17 P0040R3 Extending Memory Management Tools VS 2017.3 C++17 P0152R1 atomic::is_always_lock_free VS 2017.3 C++17 P0154R1 hardware_destructive_interference_size, etc. VS 2017.3 C++17 P0156R2 Renaming Variadic lock_guard To scoped_lock VS 2017.3 C++17 P0253R1 Fixing Searcher Return Types VS 2017.3 C++17 P0403R1 UDLs For <string_view> (“meow”sv, etc.) VS 2017.3 C++17 P0418R2 atomic compare_exchange memory_order Requirements [14] VS 2017.3 C++17 P0513R0 Poisoning hash [14] VS 2017.3 C++17 P0516R0 Marking shared_future Copying As noexcept [14] VS 2017.3 C++17 P0517R0 Constructing future_error From future_errc [14] VS 2017.3 C++17 P0558R1 Resolving atomic<T> Named Base Class Inconsistencies [I] [14] VS 2017.3 C++17 P0599R1 noexcept hash [14] 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 [J] 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 [K] 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 2013 C++17 N4510 Supporting Incomplete Types In vector/list/forward_list [14] N/A C++17 N4284 Contiguous Iterators N/A C++17 P0175R1 Synopses For The C Library N/A C++17 P0180R2 Reserving Namespaces For Future Standardization N/A C++17 P0346R1 A <random> Nomenclature Tweak N/A C++17 P0371R1 Discouraging memory_order_consume N/A C++17 P0467R2 Requiring Forward Iterators In Parallel Algorithms N/A C++17 P0502R0 Parallel Algorithms Should terminate() For Exceptions, Usually N/A C++17 P0503R0 Correcting Library Usage Of “literal type” N/A C++17 P0509R1 Updating “Restrictions on exception handling” N/A C++17 P0518R1 Copying Trivially Copy Constructible Elements In Parallel Algorithms N/A C++17 P0523R1 Relaxing Complexity Requirements Of Parallel Algorithms (General) N/A C++17 P0574R1 Relaxing Complexity Requirements Of Parallel Algorithms (Specific) N/A C++17 P0623R0 Final C++17 Parallel Algorithms Fixes

The “missing” and “patch” papers have been grouped together and should be self-explanatory. The Library Fundamentals V1 paper has been decomposed into individual features marked by “…”. Finally, “N/A” indicates papers that didn’t change normative wording, or that didn’t really result in new features for users. For example, when we implement Parallel Algorithms, we’ll implement the current Standardese. For tracking purposes, P0394R4 (Parallel Algorithms Should terminate() For Exceptions) is important for users and implementers to be aware of, while P0502R0 (Parallel Algorithms Should terminate() For Exceptions, Usually) isn’t (it permits non-Standard execution policies to have different behavior).

[G] Serial for_each_n() will be available in Preview 2.

[H] /std:c++17 and /std:c++latest enable std::byte. It can be disabled by defining _HAS_STD_BYTE to 0.

[I] We’ve implemented the user-visible parts of P0558R1 (Resolving atomic<T> Named Base Class Inconsistencies), except for the signatures of atomic_meow() and atomic_meow_explicit(), which can be observed by taking their addresses or providing explicit template arguments.

[J] /std:c++17 and /std:c++latest remove the old iostreams members. They can be restored by defining _HAS_OLD_IOSTREAMS_MEMBERS to 1.

[K] /std:c++17 and /std:c++latest remove auto_ptr, random_shuffle(), and the old <functional> stuff. They can be restored by defining _HAS_AUTO_PTR_ETC to 1.

We’ve also implemented 29 LWG issue resolutions, fixed several bugs, and made many behind-the-scenes improvements, which we’ll be writing about as we get closer to VS 2017.3’s final release.

Please try out Visual Studio 2017 version 15.3 preview and let us know what you think. (Remember that you must compile with either /std:c++17 or /std:c++latest to enable C++17 features, aside from those marked [14] above – and remember that [P2] features won’t be available until Preview 2.) You can use the IDE’s Report A Problem to report bugs. For compiler and library bugs, it’s important to provide self-contained test cases.