在VS 2015 Update 2 关于STL已实现C++ 17-so-far的功能

在VS 2015 Update 2 关于STL已实现C++ 17-so-far的功能

[原文发表地址] https://blogs.msdn.com/b/vcblog/archive/2016/01/22/vs-2015-update-2-s-stl-is-c-17-so-far-feature-complete.aspx

[原文发表时间] 01/22/2016 9:16 AM

 

在VS 2015 Update 2上,我们已经实现了C++ Standard Library的 每一个功能, 这也已经覆盖到了C++11, C++14和C++17-so-far等。参见文件N4567有关Update 2的相关信息,请见文章末尾) 详细列表如下:

Status

Std

Paper

Title

Update 2

C++14

N3462

SFINAE-Friendly result_of

Update 2

C++17

N4387

Improving pair And tuple

Up2 Win7+

C++17

N4508

shared_mutex (Untimed)

Up2 opt-in

C++17

P0004R1

Removing Deprecated Iostreams Aliases

Update 2

C++17

P0006R0

Variable Templates For Type Traits (is_same_v, etc.)

Update 2

C++17

P0007R1

as_const()

Update 2

C++17

P0013R1

Logical Operator Type Traits (conjunction, etc.)

Update 2

C++17

P0074R0

owner_less<>

Update 2

C++17

P0092R1

<chrono> floor(), ceil(), round(), abs()

Update 2

C++17

P0156R0

Variadic lock_guard

VS 2015

C++14

N3302

constexpr For <complex>

VS 2015

C++14

N3469

constexpr For <chrono>

VS 2015

C++14

N3470

constexpr For <array>

VS 2015

C++14

N3471

constexpr For <initializer_list>, <tuple>, <utility>

VS 2015

C++14

N3545

integral_constant::operator()()

VS 2015

C++14

N3642

UDLs For <chrono>, <string> (1729ms, "meow"s, etc.)

VS 2015

C++14

N3644

Null Forward Iterators

VS 2015

C++14

N3654

quoted()

VS 2015

C++14

N3657

Heterogeneous Associative Lookup

VS 2015

C++14

N3658

integer_sequence

VS 2015

C++14

N3659

shared_mutex (Timed)

VS 2015

C++14

N3668

exchange()

VS 2015

C++14

N3669

Fixing constexpr Member Functions Without const

VS 2015

C++14

N3670

get<T>()

VS 2015

C++14

N3671

Dual-Range equal(), is_permutation(), mismatch()

VS 2015

C++14

N3778

Sized Deallocation

VS 2015

C++14

N3779

UDLs For <complex> (3.14i, etc.)

VS 2015

C++14

N3789

constexpr For <functional>

VS 2015

C++14

N3887

tuple_element_t

VS 2015

C++14

N3891

Renaming shared_mutex (Timed) To shared_timed_mutex

VS 2015

C++17

N3911

void_t

VS 2015

C++17

N4089

Safe Conversions In unique_ptr<T[]>

VS 2015

C++17

N4169

invoke()

2015 opt-in

C++17

N4190

Removing auto_ptr, random_shuffle(), And Old <functional> Stuff

VS 2015

C++17

N4258

noexcept Cleanups

VS 2015

C++17

N4259

uncaught_exceptions()

VS 2015

C++17

N4277

Trivially Copyable reference_wrapper

VS 2015

C++17

N4279

insert_or_assign()/try_emplace() For map/unordered_map

VS 2015

C++17

N4280

size(), empty(), data()

VS 2015

C++17

N4366

Precisely Constraining unique_ptr Assignment

VS 2015

C++17

N4389

bool_constant

VS 2013

C++14

N3346

Minimal Container Element Requirements

VS 2013

C++14

N3421

Transparent Operator Functors (less<>, etc.)

VS 2013

C++14

N3655

Alias Templates For <type_traits> (decay_t, etc.)

VS 2013

C++14

N3656

make_unique()

VS 2013

C++17

N4510

Supporting Incomplete Types In vector/list/forward_list

N/A

C++14

N3924

Discouraging rand()

N/A

C++17

N4284

Contiguous Iterators

 

“N/A”表示那些建议只是改变了标准文档中的说法,并不会对实施者和用户有任何实质的影响。我只是为了工作的完整性才将它们作为Not Applicable类型来列举出来。

 

我们之前在Update 1中宣布了编译器开始部分支持SFINAE表达式。尽管Update 2中仍然是部分支持SFINAE表达式时,但是已经能够改进它到STL 可以精准地依赖它的程度。因此,Update 2中的STL完全支持N3462中的"SFINAE-Friendly result_of"和LWG 2132中的"std::function ambiguity"。这一结论已经在每一个build上运行全面覆盖的单元测试得到验证。(LWG 2132允许重载meow(function<void (int)>)和meow(function<void (int, int)>),并且可以允许一个或者两个int 参数的lambda 表达式来调用meow() 函数,并根据实际情况匹配相应的重载函数。)

 

在N4387"Improving pair And tuple"中有一个值得注意的结论:安全使用的前提下,元组可以作为返回值类型。例如,{ "cute","fluffy", "kittens" }可以作为tuple<string,string, string>类型被返回,因为std::string类型有一个基于const char* 的隐式构造函数。

 

N4508中的"shared_mutex(Untimed)"不支持在XP和Vista-class操作系统上使用(客户端和服务器上都是)。这是因为我们在std::shared_mutex的实施隐藏了SRWLOCK, 并且还要求OS APIs是Win7-class OSes 。比如在 std::forward_list中,std::shared_mutex就是为了给简化功能提供更低的开销。试图通过动态检查功能来支持XP/Vista, 这将会和std::shared_mutex存在的原因发生冲突。所以如果你需要在XP/Vista上使用这项功能,你就需要使提供了更加强大的功能的std::shared_timed_mutex。

 

P0004R1中的"Removing Deprecated Iostreams Aliases"现在是opt-in状态。如果你设置一个宏_HAS_OLD_IOSTREAMS_MEMBERS 为0,我们将会移除旧的机器(这个是c++98的遗留问题)。同样的,LWG2385中的 "function::assign allocator argument doesn't make sense"要求定义_HAS_FUNCTION_ASSIGN 为0,并且在N4190中的"Removing auto_ptr, random_shuffle(), And Old <functional> Stuff"要求定义_HAS_AUTO_PTR_ETC为0。在将来的主要版本中,我们打算把这些被删除的内容设置为opt-out状态,并且不对其作任何限制。

 

现在,我需要说明一下。”功能完成“并不是意味着“标准规定的每一个功能都完成了”。我们仍然漏掉了一些比起这些建议更加细小的部分:

 

* 极少数常量表达式匹配项缺失。详细内容如下:在C++11里,mutex的默认构造函数需要一个较大的表征转换(我们不能将其移到到一个Update中). In C++14, error_category的默认构造函数需要一个较小的表征转换(这个在2015 Update里也是被禁止的,但是它早已经在下一个主要版本中修复了). 最后,C++14用来初始化列表的min()/max()/minmax(以及C++17的min_element()/max_element()/minmax_element()本身包含循环,它们需要编译器支持C++14扩展常量表达式,但这一功能现在还不可用。

 

* C99 Standard Library的各项内容除了tgmath.h(这个头文件在C++中无关紧要)和CX_LIMITED_RANGE、FP_CONTRACT宏功能之外我们已经全部完成,。

 

* 在实施C++14和C++17的Library 问题的解决方案上,我们取得了一些可观的进展(具体内容见下表;LibraryIssue就是标准库本身的bug),但是有8个要在C++14上修复的bug和11个要在C++17-so-far上修复的bug还尚待执行。

 

* C++17最终版发布之前还会有许多的功能被添加进去,而且我们现在已经开始着手处理了。

 

* 我们现在还有一些bug正在修复。(到目前为止,我们已经在Update 2上修复了大约36个STL的bug了。我会在Update 2最终版本发布一份更新日志)

下面是我们的Library Issue表:

Status

Std

Issue

Title

Update 2

C++14

LWG 2005

unordered_map::insert(T&&) protection should apply to map too

Update 2

C++14

LWG 2021

Further incorrect usages of result_of

Update 2

C++14

LWG 2132

std::function ambiguity

Update 2

C++14

LWG 2196

Specification of is_*[copy/move]_[constructible/assignable] unclear for non-referencable types

Update 2

C++17

LWG 2101

Some transformation types can produce impossible types

Update 2

C++17

LWG 2106

move_iterator wrapping iterators returning prvalues

Update 2

C++17

LWG 2127

Move-construction with raw_storage_iterator

Update 2

C++17

LWG 2217

operator==(sub_match, string) slices on embedded '\0's

Update 2

C++17

LWG 2353

std::next is over-constrained

Update 2

C++17

LWG 2354

Unnecessary copying when inserting into maps with braced-init syntax

Update 2

C++17

LWG 2367

pair and tuple are not correctly implemented for is_constructible with no args

Up2 opt-in

C++17

LWG 2385

function::assign allocator argument doesn't make sense

Update 2

C++17

LWG 2455

Allocator default construction should be allowed to throw

Update 2

C++17

LWG 2466

allocator_traits::max_size() default behavior is incorrect

Update 2

C++17

LWG 2469

Wrong specification of Requires clause of operator[] for map and unordered_map

Update 2

New

LWG 2549

Tuple EXPLICIT constructor templates [...] will create dangling references

missing

C++14

LWG 2064

More noexcept issues in basic_string

missing

C++14

LWG 2078

Throw specification of async() incomplete

missing

C++14

LWG 2135

Unclear requirement for exceptions thrown in condition_variable::wait()

missing

C++14

LWG 2140

notify_all_at_thread_exit synchronization

missing

C++14

LWG 2203

scoped_allocator_adaptor uses wrong argument types for piecewise construction

missing

C++14

LWG 2210

Missing allocator-extended constructor for allocator-aware containers

missing

C++14

LWG 2252

Strong guarantee on vector::push_back() still broken with C++11?

missing

C++14

LWG 2350

min, max, and minmax should be constexpr

missing

C++17

LWG 1169

num_get not fully compatible with strto*

missing

C++17

LWG 2059

C++0x ambiguity problem with map::erase

missing

C++17

LWG 2063

Contradictory requirements for string move assignment

missing

C++17

LWG 2156

Unordered containers' reserve(n) reserves for n-1 elements

missing

C++17

LWG 2219

INVOKE-ing a pointer to member with a reference_wrapper as the object expression

missing

C++17

LWG 2369

constexpr max(initializer_list) vs max_element

missing

C++17

LWG 2408

SFINAE-friendly common_type / iterator_traits is missing in C++14

missing

C++17

LWG 2415

Inconsistency between unique_ptr and shared_ptr

missing

C++17

LWG 2439

unique_copy() sometimes can't fall back to reading its output

missing

C++17

LWG 2476

scoped_allocator_adaptor is not assignable

missing

C++17

LWG 2485

get() should be overloaded for const tuple&&

VS 2015

C++14

GB 9

Remove gets from C++14

VS 2015

C++14

LWG 2009

Reporting out-of-bound values on numeric string conversions

VS 2015

C++14

LWG 2094

duration conversion overflow shouldn't participate in overload resolution

VS 2015

C++14

LWG 2097

packaged_task constructors should be constrained

VS 2015

C++14

LWG 2103

std::allocator_traits<std::allocator<T>>::propagate_on_container_move_assignment

VS 2015

C++14

LWG 2104

unique_lock move-assignment should not be noexcept

VS 2015

C++14

LWG 2112

User-defined classes that cannot be derived from

VS 2015

C++14

LWG 2144

Missing noexcept specification in type_index

VS 2015

C++14

LWG 2145

error_category default constructor

VS 2015

C++14

LWG 2162

allocator_traits::max_size missing noexcept

VS 2015

C++14

LWG 2174

wstring_convert::converted() should be noexcept

VS 2015

C++14

LWG 2176

Special members for wstring_convert and wbuffer_convert

VS 2015

C++14

LWG 2187

vector<bool> is missing emplace and emplace_back member functions

VS 2015

C++14

LWG 2193

Default constructors for standard library containers are explicit

VS 2015

C++14

LWG 2247

Type traits and std::nullptr_t

VS 2015

C++14

LWG 2268

Setting a default argument in the declaration of a member function assign of std::basic_string

VS 2015

C++14

LWG 2272

quoted should use char_traits::eq for character comparison

VS 2015

C++14

LWG 2275

Why is forward_as_tuple not constexpr?

VS 2015

C++14

LWG 2278

User-defined literals for Standard Library types

VS 2015

C++14

LWG 2280

begin / end for arrays should be constexpr and noexcept

VS 2015

C++14

LWG 2285

make_reverse_iterator

VS 2015

C++14

LWG 2301

Why is std::tie not constexpr?

VS 2015

C++14

LWG 2306

match_results::reference should be value_type&, not const value_type&

VS 2015

C++14

LWG 2315

weak_ptr should be movable

VS 2015

C++14

LWG 2324

Insert iterator constructors should use addressof()

VS 2015

C++14

LWG 2329

regex_match()/regex_search() with match_results should forbid temporary strings

VS 2015

C++14

LWG 2332

regex_iterator/regex_token_iterator should forbid temporary regexes

VS 2015

C++14

LWG 2339

Wording issue in nth_element

VS 2015

C++14

LWG 2344

quoted()'s interaction with padding is unclear

VS 2015

C++14

LWG 2346

integral_constant's member functions should be marked noexcept

VS 2015

C++17

LWG 2129

User specializations of std::initializer_list

VS 2015

C++17

LWG 2133

Attitude to overloaded comma for iterators

VS 2015

C++17

LWG 2212

tuple_size for const pair request header

VS 2015

C++17

LWG 2234

assert() should allow usage in constant expressions

VS 2015

C++17

LWG 2365

Missing noexcept in shared_ptr::shared_ptr(nullptr_t)

VS 2015

C++17

LWG 2399

shared_ptr's constructor from unique_ptr should be constrained

VS 2015

C++17

LWG 2400

shared_ptr's get_deleter() should use addressof()

VS 2015

C++17

LWG 2401

std::function needs more noexcept

VS 2015

C++17

LWG 2403

stof() should call strtof() and wcstof()

VS 2015

C++17

LWG 2407

packaged_task(allocator_arg_t, const Allocator&, F&&) should neither be constrained nor explicit

VS 2015

C++17

LWG 2420

function<void(ArgTypes...)> does not discard the return value of the target object

VS 2015

C++17

LWG 2433

uninitialized_copy()/etc. should tolerate overloaded operator&

VS 2015

C++17

LWG 2440

seed_seq::size() should be noexcept

VS 2015

C++17

LWG 2442

call_once() shouldn't DECAY_COPY()

VS 2015

C++17

LWG 2454

Add raw_storage_iterator::base() member

VS 2015

C++17

LWG 2458

N3778 and new library deallocation signatures

VS 2015

C++17

LWG 2464

try_emplace and insert_or_assign misspecified

VS 2015

C++17

LWG 2467

is_always_equal has slightly inconsistent default

VS 2015

C++17

LWG 2483

throw_with_nested() should use is_final

VS 2015

C++17

LWG 2484

rethrow_if_nested() is doubly unimplementable

VS 2015

C++17

LWG 2486

mem_fn() should be required to use perfect forwarding

VS 2015

C++17

LWG 2487

bind() should be const-overloaded, not cv-overloaded

VS 2015

C++17

LWG 2488

Placeholders should be allowed and encouraged to be constexpr

VS 2015

C++17

LWG 2489

mem_fn() should be noexcept

VS 2013

C++14

LWG 1214

Insufficient/inconsistent key immutability requirements for associative containers

VS 2013

C++14

LWG 2011

Unexpected output required of strings

VS 2013

C++14

LWG 2018

regex_traits::isctype Returns clause is wrong

VS 2013

C++14

LWG 2033

Preconditions of reserve, shrink_to_fit, and resize functions

VS 2013

C++14

LWG 2039

Issues with std::reverse and std::copy_if

VS 2013

C++14

LWG 2047

Incorrect "mixed" move-assignment semantics of unique_ptr

VS 2013

C++14

LWG 2049

is_destructible is underspecified

VS 2013

C++14

LWG 2050

Unordered associative containers do not use allocator_traits to define member types

VS 2013

C++14

LWG 2056

future_errc enums start with value 0 (invalid value for broken_promise)

VS 2013

C++14

LWG 2061

make_move_iterator and arrays

VS 2013

C++14

LWG 2067

packaged_task should have deleted copy c'tor with const parameter

VS 2013

C++14

LWG 2074

Off by one error in std::reverse_copy

VS 2013

C++14

LWG 2083

const-qualification on weak_ptr::owner_before

VS 2013

C++14

LWG 2087

iostream_category() and noexcept

VS 2013

C++14

LWG 2096

Incorrect constraints of future::get in regard to MoveAssignable

VS 2013

C++14

LWG 2128

Absence of global functions cbegin/cend

VS 2013

C++14

LWG 2138

atomic_flag::clear ordering constraints

VS 2013

C++14

LWG 2141

common_type trait produces reference types

VS 2013

C++14

LWG 2143

ios_base::xalloc should be thread-safe

VS 2013

C++14

LWG 2148

Hashing enums should be supported directly by std::hash

VS 2013

C++14

LWG 2188

Reverse iterator does not fully support targets that overload operator&

VS 2013

C++14

LWG 2197

Specification of is_[un]signed unclear for non-arithmetic types

VS 2013

C++14

LWG 2213

Return value of std::regex_replace

VS 2013

C++14

LWG 2229

Standard code conversion facets underspecified

VS 2013

C++14

LWG 2284

Inconsistency in allocator_traits::max_size

VS 2013

C++14

LWG 2293

Wrong facet used by num_put::do_put

VS 2013

C++14

LWG 2313

tuple_size should always derive from integral_constant

VS 2013

C++14

LWG 2317

The type property queries should be UnaryTypeTraits returning size_t

VS 2013

C++14

LWG 2330

regex("meow", regex::icase) is technically forbidden but should be permitted

VS 2013

C++14

LWG 2341

Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir)

VS 2013

C++14

LWG 2359

How does regex_constants::nosubs affect basic_regex::mark_count()?

VS 2013

C++14

LWG 2360

reverse_iterator::operator*() is unimplementable

VS 2013

C++17

LWG 2244

Issue on basic_istream::seekg

VS 2013

C++17

LWG 2273

regex_match ambiguity

VS 2013

C++17

LWG 2473

basic_filebuf's relation to C FILE semantics

 

我省略了125个N/A类型的问题,这些问题目前实施者要求不做任何处理的。这儿有一个很特别的问题。关于LWG 2549 "Tuple EXPLICIT constructor templates [...] will create dangling references"的解决方案虽然还没有被C++17采纳,但是我完成它并将其列在这里是因为它有助于我顺利完成C++17的 N4387 "Improving pair And tuple"。

 

常见问题解答

Q: 你在完成C++11compiler功能之前在实施C++17的library的功能。

A: 这不算问题。

 

Q: 为什么?

A: 好很多了。至少有两个原因可以说明。第一,library开发者和compiler开发者是不能相互替换的。Library的代码库和compiler的代码库也是完全不同的,并且我们所有的高级C++程序员所必备的library和compiler开发技能是没有交集的,这在很大程度上和人们想的不同。并且同时从事这两项工作的几率是很小的(Gor Nishanov是个例外; 他即将成为这两项工作的技术支持)。关于STL取得的成果也不会隐瞒Compiler
组,这是事实!第二,STL开发影响到compiler功能时也会使编译器更加健壮。举些例子:在STL中实施result_of/function
SFINAE也会改善编译器上正在实施的C++11 SFINAE表达式(指向数据成员的指针表达式确实比较棘手),在STL中实施C++11/14/17中的每一个常量表达式也使得编译器对C++11常量表达式的支持得到大量的改善,还有实施的C++17 pair/tuple的一些修改(SFINAE在STL上的一些新用法)还发现了许多编译器上现存的bug。所以,所有的这些STL的工作都间接的优化了编译器,特别是对那些类似STL功能的代码(比如Boost库)。

 

Q: 编译器有什么新东西?

A: 我们会对这个编译器发布一个最新的功能表,除了自RTM以来的改变:Update 1中部分支持SFINAE表达式和在Update 2中支持变量模板(还有使用STL的is_same_v等等)。然而,变量模板在C1XX和Clang中还是受限的,编译器前端被用来生成实际代码。在Update 2用来智能感应的EDG前端是不支持变量模板的(计划在Update 3中支持)。因此,当使用编译器或STL的变量模板时,IDE界面上会出现红色波浪线来警告。虽然不同寻常,我们还是认为这比人为阻碍C1XX/STL对其支持要更好。

 

Q: 最近一次STL组赶上C++ Working Paper的计划是什么时候?

A: 2006年,在TR1被加入C++0x之前。

 

Q: 最近一次你在主版本之外发布STL功能是什么时候?

A: 2008年的SP1,当时我们增加了TR1。

 

Q: C++17听起来有点超前。你实施这些C++17的STL功能只是实验还是其他什么?

A: 我所做的一切都是支持在产品上使用的。我亲自检查了每一行代码,我确信都很棒。当然,在最终版本发布之前C++ Standardization Committee可以修改C++17中的任何内容,但是已经加入C++ Working Paper里的东西还是基本不会发生变化的。

 

Q: Community版的VS能使用这些功能吗?

A: 当然了。我们不愿也不能在不同版本的VS上提供不同层次的STL。

 

Q: STL接下来会有什么变化?

A: 我们接下来会去修复更多的bug,特别是性能方面的。之后,我们会去处理其他的Library Issue,添加更多新功能,并且还会去研究其他的技术规范(现在还没定下来的)。

 

Q: Update 2的这些功能什么时候能用?

A: 我们还没公开宣布这些功能,但是第一个预览版本中将会包含这些功能这些都是迟早的事情(TM)

 

Q: 我现在可以使用这些新功能吗?

A: 当然! 我们已经在Visual C++webcompiler上更新了我们当前的开发内容,所以你可以编译示例程序去尝试这新功能。

 

我会在Update 2预览版发布时下载链接上更新这篇文章,并且会在最终版发布时再更新一次。你现在就可以下载VS 2015 Update 1 的Community版本,这个版本支持上面所有紫色和蓝色表格的内容。

特别感谢Billy O'Neal (@MalwareMinigun)和Steve Wishnousky (@SteveWishnousky)的帮助,我们才能这么快完成这些功能、问题和bug修复。

 

Stephan T. Lavavej (@StephanTLavavej)

Visual C++ Libraries高级开发工程师

stl@microsoft.com