在VS 2015 Update 2 关于STL已实现C++ 17-so-far的功能
在VS 2015 Update 2 关于STL已实现C++ 17-so-far的功能
[原文发表时间] 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 |
SFINAE-Friendly result_of |
|
Update 2 |
C++17 |
Improving pair And tuple |
|
Up2 Win7+ |
C++17 |
shared_mutex (Untimed) |
|
Up2 opt-in |
C++17 |
Removing Deprecated Iostreams Aliases |
|
Update 2 |
C++17 |
Variable Templates For Type Traits (is_same_v, etc.) |
|
Update 2 |
C++17 |
as_const() |
|
Update 2 |
C++17 |
Logical Operator Type Traits (conjunction, etc.) |
|
Update 2 |
C++17 |
owner_less<> |
|
Update 2 |
C++17 |
<chrono> floor(), ceil(), round(), abs() |
|
Update 2 |
C++17 |
Variadic lock_guard |
|
VS 2015 |
C++14 |
constexpr For <complex> |
|
VS 2015 |
C++14 |
constexpr For <chrono> |
|
VS 2015 |
C++14 |
constexpr For <array> |
|
VS 2015 |
C++14 |
constexpr For <initializer_list>, <tuple>, <utility> |
|
VS 2015 |
C++14 |
integral_constant::operator()() |
|
VS 2015 |
C++14 |
UDLs For <chrono>, <string> (1729ms, "meow"s, etc.) |
|
VS 2015 |
C++14 |
Null Forward Iterators |
|
VS 2015 |
C++14 |
quoted() |
|
VS 2015 |
C++14 |
Heterogeneous Associative Lookup |
|
VS 2015 |
C++14 |
integer_sequence |
|
VS 2015 |
C++14 |
shared_mutex (Timed) |
|
VS 2015 |
C++14 |
exchange() |
|
VS 2015 |
C++14 |
Fixing constexpr Member Functions Without const |
|
VS 2015 |
C++14 |
get<T>() |
|
VS 2015 |
C++14 |
Dual-Range equal(), is_permutation(), mismatch() |
|
VS 2015 |
C++14 |
Sized Deallocation |
|
VS 2015 |
C++14 |
UDLs For <complex> (3.14i, etc.) |
|
VS 2015 |
C++14 |
constexpr For <functional> |
|
VS 2015 |
C++14 |
tuple_element_t |
|
VS 2015 |
C++14 |
Renaming shared_mutex (Timed) To shared_timed_mutex |
|
VS 2015 |
C++17 |
void_t |
|
VS 2015 |
C++17 |
Safe Conversions In unique_ptr<T[]> |
|
VS 2015 |
C++17 |
invoke() |
|
2015 opt-in |
C++17 |
Removing auto_ptr, random_shuffle(), And Old <functional> Stuff |
|
VS 2015 |
C++17 |
noexcept Cleanups |
|
VS 2015 |
C++17 |
uncaught_exceptions() |
|
VS 2015 |
C++17 |
Trivially Copyable reference_wrapper |
|
VS 2015 |
C++17 |
insert_or_assign()/try_emplace() For map/unordered_map |
|
VS 2015 |
C++17 |
size(), empty(), data() |
|
VS 2015 |
C++17 |
Precisely Constraining unique_ptr Assignment |
|
VS 2015 |
C++17 |
bool_constant |
|
VS 2013 |
C++14 |
Minimal Container Element Requirements |
|
VS 2013 |
C++14 |
Transparent Operator Functors (less<>, etc.) |
|
VS 2013 |
C++14 |
Alias Templates For <type_traits> (decay_t, etc.) |
|
VS 2013 |
C++14 |
make_unique() |
|
VS 2013 |
C++17 |
Supporting Incomplete Types In vector/list/forward_list |
|
N/A |
C++14 |
Discouraging rand() |
|
N/A |
C++17 |
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 |
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