From de589f2f8f9498f8006dc954e177a195ef6eb136 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sat, 21 Sep 2013 21:13:54 +0000 Subject: [PATCH] Peter Collingbourne: If a pointer is passed as the third argument of the (iterator, iterator, allocator) constructor with the intention of it being implicitly converted to the allocator type, it is possible for overload resolution to favour the (iterator, iterator, enable_if) constructor. Eliminate this possibility by moving the enable_if to one of the existing arguments and removing the third argument. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@191145 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/vector | 20 +++++++++++-------- .../construct_iter_iter_alloc.pass.cpp | 16 +++++++++++++-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/include/vector b/include/vector index 258a950d..619faaa5 100644 --- a/include/vector +++ b/include/vector @@ -524,12 +524,13 @@ public: vector(size_type __n, const_reference __x); vector(size_type __n, const_reference __x, const allocator_type& __a); template - vector(_InputIterator __first, _InputIterator __last, + vector(_InputIterator __first, typename enable_if<__is_input_iterator <_InputIterator>::value && !__is_forward_iterator<_InputIterator>::value && is_constructible< value_type, - typename iterator_traits<_InputIterator>::reference>::value>::type* = 0); + typename iterator_traits<_InputIterator>::reference>::value, + _InputIterator>::type __last); template vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a, typename enable_if<__is_input_iterator <_InputIterator>::value && @@ -538,11 +539,12 @@ public: value_type, typename iterator_traits<_InputIterator>::reference>::value>::type* = 0); template - vector(_ForwardIterator __first, _ForwardIterator __last, + vector(_ForwardIterator __first, typename enable_if<__is_forward_iterator<_ForwardIterator>::value && is_constructible< value_type, - typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0); + typename iterator_traits<_ForwardIterator>::reference>::value, + _ForwardIterator>::type __last); template vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a, typename enable_if<__is_forward_iterator<_ForwardIterator>::value && @@ -1072,12 +1074,13 @@ vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x, const alloca template template -vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, +vector<_Tp, _Allocator>::vector(_InputIterator __first, typename enable_if<__is_input_iterator <_InputIterator>::value && !__is_forward_iterator<_InputIterator>::value && is_constructible< value_type, - typename iterator_traits<_InputIterator>::reference>::value>::type*) + typename iterator_traits<_InputIterator>::reference>::value, + _InputIterator>::type __last) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1105,11 +1108,12 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c template template -vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, +vector<_Tp, _Allocator>::vector(_ForwardIterator __first, typename enable_if<__is_forward_iterator<_ForwardIterator>::value && is_constructible< value_type, - typename iterator_traits<_ForwardIterator>::reference>::value>::type*) + typename iterator_traits<_ForwardIterator>::reference>::value, + _ForwardIterator>::type __last) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); diff --git a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp index e386297c..afc8ea5d 100644 --- a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp +++ b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp @@ -19,9 +19,9 @@ #include "../../../stack_allocator.h" #include "../../../min_allocator.h" -template +template void -test(Iterator first, Iterator last, const typename C::allocator_type& a) +test(Iterator first, Iterator last, const A& a) { C c(first, last, a); assert(c.__invariants()); @@ -30,6 +30,17 @@ test(Iterator first, Iterator last, const typename C::allocator_type& a) assert(*i == *first); } +#if __cplusplus >= 201103L + +template +struct implicit_conv_allocator : min_allocator +{ + implicit_conv_allocator(void* p) {} + implicit_conv_allocator(const implicit_conv_allocator&) = default; +}; + +#endif + int main() { { @@ -52,6 +63,7 @@ int main() test> >(bidirectional_iterator(a), bidirectional_iterator(an), alloc); test> >(random_access_iterator(a), random_access_iterator(an), alloc); test> >(a, an, alloc); + test> >(a, an, nullptr); } #endif }