Document number: N3673
Date: 2013-04-19
Author: Daniel Krügler
Project: Programming Language C++, Library Working Group
Reply-to: Daniel Krügler

C++ Library Working Group Ready Issues Bristol 2013

Proposed resolution

2094. duration conversion overflow shouldn't participate in overload resolution

This wording is relative to the FDIS.

Change the following paragraphs of 20.11.5.1 [time.duration.cons] p4 indicated:

template <class Rep2, class Period2>
  constexpr duration(const duration<Rep2, Period2>& d);

Remarks: This constructor shall not participate in overload resolution unless no overflow is induced in the conversion and treat_as_floating_point<rep>::value is true or both ratio_divide<Period2, period>::den is 1 and treat_as_floating_point<Rep2>::value is false. [ Note: This requirement prevents implicit truncation error when converting between integral-based duration types. Such a construction could easily lead to confusion about the value of the duration. - end note ]

2122. merge() stability for lists versus forward lists

This wording is relative to the N3485.

  1. Change 17.6.5.7 [algorithm.stable]/1 as indicated:

    When the requirements for an algorithm state that it is "stable" without further elaboration, it means:

    [.]

    • For the merge algorithms, for equivalent elements in the original two ranges, the elements from the first range (preserving their original order) precede the elements from the second range (preserving their original order).
  2. Change 23.3.4.6 [forwardlist.ops] as indicated:

    void remove(const T& value);
    template <class Predicate> void remove_if(Predicate pred);
    

    -12- Effects: Erases all the elements in the list referred by a list iterator i for which the following conditions hold: *i == value (for remove()), pred(*i) is true (for remove_if()). This operation shall be stable: the relative order of the elements that are not removed is the same as their relative order in the original list. Invalidates only the iterators and references to the erased elements.

    -13- Throws: Nothing unless an exception is thrown by the equality comparison or the predicate.

    -??- Remarks: Stable (17.6.5.7 [algorithm.stable]).

    [.]

    void merge(forward_list& x);
    void merge(forward_list&& x);
    template <class Compare> void merge(forward_list& x, Compare comp)
    template <class Compare> void merge(forward_list&& x, Compare comp)
    

    [.]

    -19- Effects: Merges x into *thisthe two sorted ranges [begin(), end()) and [x.begin(), x.end()). This operation shall be stable: for equivalent elements in the two lists, the elements from *this shall always precede the elements from x. x is empty after the merge. If an exception is thrown other than by a comparison there are no effects. Pointers and references to the moved elements of x now refer to those same elements but as members of *this. Iterators referring to the moved elements will continue to refer to their elements, but they now behave as iterators into *this, not into x.

    -20- Remarks: Stable (17.6.5.7 [algorithm.stable]). The behavior is undefined if this->get_allocator() != x.get_allocator().

    [.]

    void sort();
    template <class Compare> void sort(Compare comp);
    

    [.]

    -23- Effects: Sorts the list according to the operator< or the comp function object. This operation shall be stable: the relative order of the equivalent elements is preserved. If an exception is thrown the order of the elements in *this is unspecified. Does not affect the validity of iterators and references.

    -??- Remarks: Stable (17.6.5.7 [algorithm.stable]).

    [.]

  3. Change 23.3.5.5 [list.ops] as indicated:

    void remove(const T& value);
    template <class Predicate> void remove_if(Predicate pred);
    

    [.]

    -17- Remarks: Stable (17.6.5.7 [algorithm.stable]).

    [.]

    void merge(list& x);
    void merge(list&& x);
    template <class Compare> void merge(list& x, Compare comp)
    template <class Compare> void merge(list&& x, Compare comp)
    

    [.]

    -24- Remarks: Stable (17.6.5.7 [algorithm.stable]). [.]

    [.]

    void sort();
    template <class Compare> void sort(Compare comp);
    

    [.]

    -30- Remarks: Stable (17.6.5.7 [algorithm.stable]).

    [.]

  4. Change 25.3.1 [alg.copy]/12 as indicated:

    template<class InputIterator, class OutputIterator, class Predicate>
    OutputIterator 
    copy_if(InputIterator first, InputIterator last,
            OutputIterator result, Predicate pred);
    

    [.]

    -12- Remarks: Stable (17.6.5.7 [algorithm.stable]).

  5. Change 25.3.8 [alg.remove] as indicated:

    template<class ForwardIterator, class T>
    ForwardIterator 
    remove(ForwardIterator first, ForwardIterator last, const T& value);
    template<class ForwardIterator, class Predicate>
    ForwardIterator 
    remove_if(ForwardIterator first, ForwardIterator last, Predicate pred);
    

    [.]

    -4- Remarks: Stable (17.6.5.7 [algorithm.stable]).

    [.]

    template<class InputIterator, class OutputIterator, class T>
    OutputIterator
    remove_copy(InputIterator first, InputIterator last,
                OutputIterator result, const T& value);
    template<class InputIterator, class OutputIterator, class Predicate>
    OutputIterator
    remove_copy_if(InputIterator first, InputIterator last,
                   OutputIterator result, Predicate pred);
    

    [.]

    -11- Remarks: Stable (17.6.5.7 [algorithm.stable]).

  6. Change 25.4.1.2 [stable.sort]/4 as indicated:

    template<class RandomAccessIterator>
    void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
    template<class RandomAccessIterator, class Compare>
    void stable_sort(RandomAccessIterator first, RandomAccessIterator last,
    Compare comp);
    

    [.]

    -4- Remarks: Stable (17.6.5.7 [algorithm.stable]).

  7. Change 25.4.4 [alg.merge] as indicated:

    template<class InputIterator1, class InputIterator2,
             class OutputIterator>
    OutputIterator
    merge(InputIterator1 first1, InputIterator1 last1,
          InputIterator2 first2, InputIterator2 last2,
          OutputIterator result);
    template<class InputIterator1, class InputIterator2,
             class OutputIterator, class Compare>
    OutputIterator
    merge(InputIterator1 first1, InputIterator1 last1,
          InputIterator2 first2, InputIterator2 last2,
          OutputIterator result, Compare comp);
    

    [.]

    -5- Remarks: Stable (17.6.5.7 [algorithm.stable]).

    [.]

    template<class BidirectionalIterator>
    void inplace_merge(BidirectionalIterator first,
                       BidirectionalIterator middle,
                       BidirectionalIterator last);
    template<class BidirectionalIterator, class Compare>
    void inplace_merge(BidirectionalIterator first,
                       BidirectionalIterator middle,
                       BidirectionalIterator last, Compare comp);
    

    [.]

    -9- Remarks: Stable (17.6.5.7 [algorithm.stable]).

2128. Absence of global functions cbegin/cend

This wording is relative to N3485.

  1. In 24.3 [iterator.synopsis], header iterator synopsis, add the following declarations:

    namespace std {
      [.]
      // 24.6.5, range access:
      template <class C> auto begin(C& c) -> decltype(c.begin());
      template <class C> auto begin(const C& c) -> decltype(c.begin());
      template <class C> auto end(C& c) -> decltype(c.end());
      template <class C> auto end(const C& c) -> decltype(c.end());
      template <class T, size_t N> T* begin(T (&array)[N]);
      template <class T, size_t N> T* end(T (&array)[N]);
      template <class C> auto cbegin(const C& c) -> decltype(std::begin(c));
      template <class C> auto cend(const C& c) -> decltype(std::end(c));
      template <class C> auto rbegin(C& c) -> decltype(c.rbegin());
      template <class C> auto rbegin(const C& c) -> decltype(c.rbegin());
      template <class C> auto rend(C& c) -> decltype(c.rend());
      template <class C> auto rend(const C& c) -> decltype(c.rend());
      template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);
      template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);
      template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il);
      template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);
      template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));
      template <class C> auto crend(const C& c) -> decltype(std::rend(c));
    }
    
  2. At the end of 24.7 [iterator.range], add:

    template <class C> auto cbegin(const C& c) -> decltype(std::begin(c));
    

    -?- Returns: std::begin(c).

    template <class C> auto cend(const C& c) -> decltype(std::end(c));
    

    -?- Returns: std::end(c).

    template <class C> auto rbegin(C& c) -> decltype(c.rbegin());
    template <class C> auto rbegin(const C& c) -> decltype(c.rbegin());
    

    -?- Returns: c.rbegin().

    template <class C> auto rend(C& c) -> decltype(c.rend());
    template <class C> auto rend(const C& c) -> decltype(c.rend());
    

    -?- Returns: c.rend().

    template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);
    

    -?- Returns: reverse_iterator<T*>(array + N).

    template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);
    

    -?- Returns: reverse_iterator<T*>(array).

    template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il);
    

    -?- Returns: reverse_iterator<const E*>(il.end()).

    template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);
    

    -?- Returns: reverse_iterator<const E*>(il.begin()).

    template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));
    

    -?- Returns: std::rbegin(c).

    template <class C> auto crend(const C& c) -> decltype(std::rend(c));
    

    -?- Returns: std::rend(c).

2148. Hashing enums should be supported directly by std::hash

This wording is relative to N3485.

  1. In 20.8 [function.objects], header functional synopsis, edit as indicated:

    namespace std {
      [.]
      // 20.8.12, hash function baseprimary template:
      template <class T> struct hash;
      [.]
    }
    
  2. In 20.8.12 [unord.hash]/1 edit as indicated:

    -1- The unordered associative containers defined in 23.5 [unord] use specializations of the class template hash as the default hash function. For all object types Key for which there exists a specialization hash<Key>, and for all enumeration types (7.2 [dcl.enum]) Key, the instantiation hash<Key> shall: [.]

2149. Concerns about 20.8/5

This wording is relative to N3485.

Edit 20.8 [function.objects] p5:

[Note:To enable adaptors and other components to manipulate function objects that take one or two arguments it is required that the function objectsmany of the function objects in this clause correspondingly provide typedefs argument_type and result_type for function objects that take one argument and first_argument_type, second_argument_type, and result_type for function objects that take two arguments.- end note]

2162. allocator_traits::max_size missing noexcept

In 20.6.8 [allocator.traits] and 20.6.8.2 [allocator.traits.members]/7, change the function signature to

static size_type max_size(Alloc& a) noexcept;

2176. Special members for wstring_convert and wbuffer_convert

This wording is relative to N3376.

  1. Edit the class template wstring_convert synopsis in 22.3.3.2.2 [conversions.string] p2:

    explicit wstring_convert(Codecvt *pcvt = new Codecvt);
    wstring_convert(Codecvt *pcvt, state_type state);
    explicit wstring_convert(const byte_string& byte_err,
                             const wide_string& wide_err = wide_string());
    ~wstring_convert();
    
    wstring_convert(const wstring_convert&) = delete;
    wstring_convert& operator=(const wstring_convert&) = delete;
    				 
    
  2. Edit the signatures before 22.3.3.2.2 [conversions.string] p16:

    explicit wstring_convert(Codecvt *pcvt = new Codecvt);
    wstring_convert(Codecvt *pcvt, state_type state);
    explicit wstring_convert(const byte_string& byte_err,
        const wide_string& wide_err = wide_string());
    
  3. Edit the class template wbuffer_convert synopsis in 22.3.3.2.3 [conversions.buffer] p2:

    explicit wbuffer_convert(std::streambuf *bytebuf = 0,
                             Codecvt *pcvt = new Codecvt,
                             state_type state = state_type());
    
    ~wbuffer_convert();
    
    wbuffer_convert(const wbuffer_convert&) = delete;
    wbuffer_convert& operator=(const wbuffer_convert&) = delete;
    						 
    
  4. Edit the signature before 22.3.3.2.3 [conversions.buffer] p10:

    explicit wbuffer_convert(std::streambuf *bytebuf = 0,
        Codecvt *pcvt = new Codecvt, state_type state = state_type());
    

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

This wording is relative to N3376.

  1. Add the following new definition to 17.3 [definitions] as indicated:

    referenceable type [defns.referenceable]

    An object type, a function type that does not have cv-qualifiers or a ref-qualifier, or a reference type. [Note: The term describes a type to which a reference can be created, including reference types. - end note]

  2. Change Table 49 as indicated:

    Table 49 - Type property predicates
    Template Condition Preconditions
    template <class T>
    struct is_copy_constructible;
    For a referenceable type T, the same result as
    is_constructible<T,
    const T&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    template <class T>
    struct is_move_constructible;
    For a referenceable type T, the same result as
    is_constructible<T,
    T&&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    .
    template <class T>
    struct is_copy_assignable;
    For a referenceable type T, the same result as
    is_assignable<T&,
    const T&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    template <class T>
    struct is_move_assignable;
    For a referenceable type T, the same result as
    is_assignable<T&,
    T&&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    .
    template <class T>
    struct is_trivially_copy_constructible;
    For a referenceable type T, the same result as
    is_trivially_constructible<T,
    const T&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    template <class T>
    struct is_trivially_move_constructible;
    For a referenceable type T, the same result as
    is_trivially_constructible<T,
    T&&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    .
    template <class T>
    struct is_trivially_copy_assignable;
    For a referenceable type T, the same result as
    is_trivially_assignable<T&,
    const T&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    template <class T>
    struct is_trivially_move_assignable;
    For a referenceable type T, the same result as
    is_trivially_assignable<T&,
    T&&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    .
    template <class T>
    struct is_nothrow_copy_constructible;
    For a referenceable type T, the same result as
    is_nothrow_constructible<T,
    const T&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    template <class T>
    struct is_nothrow_move_constructible;
    For a referenceable type T, the same result as
    is_nothrow_constructible<T,
    T&&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    .
    template <class T>
    struct is_nothrow_copy_assignable;
    For a referenceable type T, the same result as
    is_nothrow_assignable<T&,
    const T&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.
    template <class T>
    struct is_nothrow_move_assignable;
    For a referenceable type T, the same result as
    is_nothrow_assignable<T&,
    T&&>::value is true, otherwise false.
    T shall be a complete type,
    (possibly cv-qualified) void, or an
    array of unknown bound.

2203. scoped_allocator_adaptor uses wrong argument types for piecewise construction

This wording is relative to N3376.

  1. Change 20.12.4 [allocator.adaptor.members] paragraph 11 as indicated:

    -11- Effects: Constructs a tuple object xprime from x by the following rules:

    • If uses_allocator<T1, inner_allocator_type>::value is false and is_constructible<T1, Args1...>::value is true, then xprime is x.

    • Otherwise, if uses_allocator<T1, inner_allocator_type>::value is true and is_constructible<T1, allocator_arg_t, inner_allocator_type, Args1...>::value is true, then xprime is tuple_cat(tuple<allocator_arg_t, inner_allocator_type&>( allocator_arg, inner_allocator_type()), std::move(x)).

    • Otherwise, if uses_allocator<T1, inner_allocator_type>::value is true and is_constructible<T1, Args1..., inner_allocator_type>::value is true, then xprime is tuple_cat(std::move(x), tuple<inner_allocator_type&>(inner_allocator_type())).

    • Otherwise, the program is ill-formed.

    and constructs a tuple object yprime from y by the following rules:

    • If uses_allocator<T2, inner_allocator_type>::value is false and is_constructible<T2, Args2...>::value is true, then yprime is y.

    • Otherwise, if uses_allocator<T2, inner_allocator_type>::value is true and is_constructible<T2, allocator_arg_t, inner_allocator_type, Args2...>::value is true, then yprime is tuple_cat(tuple<allocator_arg_t, inner_allocator_type&>( allocator_arg, inner_allocator_type()), std::move(y)).

    • Otherwise, if uses_allocator<T2, inner_allocator_type>::value is true and is_constructible<T2, Args2..., inner_allocator_type>::value is true, then yprime is tuple_cat(std::move(y), tuple<inner_allocator_type&>(inner_allocator_type())).

    • Otherwise, the program is ill-formed.

    then calls OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, piecewise_construct, std::move(xprime), std::move(yprime)).

2207. basic_string::at should not have a Requires clause

This wording is relative to N3376.

  1. Remove 21.4.5 [string.access] p5:

    const_reference at(size_type pos) const;
    reference at(size_type pos);
    

    -5- Requires: pos < size()

    -6- Throws: out_of_range if pos >= size().

    -7- Returns: operator[](pos).

2210. Missing allocator-extended constructor for allocator-aware containers

This wording is relative to N3485.

  1. Edit the synopsis in 23.3.3.1 [deque.overview]/2:

    namespace std {
      template <class T, class Allocator = allocator<T> >
      class deque {
      public:
        [.]
        explicit deque(const Allocator& = Allocator());
        explicit deque(size_type n, const Allocator& = Allocator());
        [.]
      };
    }
    
  2. Edit 23.3.3.2 [deque.cons]/2:

    explicit deque(size_type n, const Allocator& = Allocator());
    

    -3- Effects: Constructs a deque with n default-inserted elements using the specified allocator.

  3. Edit the synopsis in 23.3.4.1 [forwardlist.overview]/3:

    namespace std {
      template <class T, class Allocator = allocator<T> >
      class forward_list {
      public:
        [.]
        explicit forward_list(const Allocator& = Allocator());
        explicit forward_list(size_type n, const Allocator& = Allocator());
        [.]
      };
    }
    
  4. Edit 23.3.4.2 [forwardlist.cons]/3:

    explicit forward_list(size_type n, const Allocator& = Allocator());
    

    -3- Effects: Constructs a forward_list object with n default-inserted elements using the specified allocator.

  5. Edit the synopsis in 23.3.5.1 [list.overview]/2:

    namespace std {
      template <class T, class Allocator = allocator<T> >
      class list {
      public:
        [.]
        explicit list(const Allocator& = Allocator());
        explicit list(size_type n, const Allocator& = Allocator());
        [.]
      };
    }
    
  6. Edit 23.3.5.2 [list.cons]/3:

    explicit list(size_type n, const Allocator& = Allocator());
    

    -3- Effects: Constructs a list with n default-inserted elements using the specified allocator.

  7. Edit the synopsis in 23.3.6.1 [vector.overview]/2:

    namespace std {
      template <class T, class Allocator = allocator<T> >
      class vector {
      public:
        [.]
        explicit vector(const Allocator& = Allocator());
        explicit vector(size_type n, const Allocator& = Allocator());
        [.]
      };
    }
    
  8. Edit 23.3.6.2 [vector.cons]/3:

    explicit vector(size_type n, const Allocator& = Allocator());
    

    -3- Effects: Constructs a vector with n default-inserted elements using the specified allocator.

  9. Edit the synopsis in 23.3.7 [vector.bool]/1:

    namespace std {
      template <class Allocator> class vector<bool, Allocator> {
      class vector {
      public:
        [.]
        explicit vector(const Allocator& = Allocator());
        explicit vector(size_type n, const Allocator& = Allocator());
        explicit vector(size_type n, const bool& value = bool(),
                        const Allocator& = Allocator());
        [.]
      };
    }
    
  10. Add to the synopsis in 23.4.4.1 [map.overview] p2:

    namespace std {
      template <class Key, class T, class Compare = less<Key>,
        class Allocator = allocator<pair<const Key, T> > > {
      class map {
      public:
        [.]
        map(initializer_list<value_type>,
          const Compare& = Compare(),
          const Allocator& = Allocator());
        template <class InputIterator>
        map(InputIterator first, InputIterator last, const Allocator& a)
          : map(first, last, Compare(), a) { }
        map(initializer_list<value_type> il, const Allocator& a)
          : map(il, Compare(), a) { }
        ~map();
        [.]
      };
    }
    
  11. Add to the synopsis in 23.4.5.1 [multimap.overview] p2:

    namespace std {
      template <class Key, class T, class Compare = less<Key>,
        class Allocator = allocator<pair<const Key, T> > > {
      class multimap {
      public:
        [.]
        multimap(initializer_list<value_type>,
          const Compare& = Compare(),
          const Allocator& = Allocator());
        template <class InputIterator>
        multimap(InputIterator first, InputIterator last, const Allocator& a)
          : multimap(first, last, Compare(), a) { }
        multimap(initializer_list<value_type> il, const Allocator& a)
          : multimap(il, Compare(), a) { }
        ~multimap();
        [.]
      };
    }
    
  12. Add to the synopsis in 23.4.6.1 [set.overview] p2:

    namespace std {
      template <class Key, class Compare = less<Key>,
        class Allocator = allocator<Key> > {
      class set {
      public:
        [.]
        set(initializer_list<value_type>,
          const Compare& = Compare(),
          const Allocator& = Allocator());
        template <class InputIterator>
        set(InputIterator first, InputIterator last, const Allocator& a)
          : set(first, last, Compare(), a) { }
        set(initializer_list<value_type> il, const Allocator& a)
          : set(il, Compare(), a) { }
        ~set();
        [.]
      };
    }
    
  13. Add to the synopsis in 23.4.7.1 [multiset.overview] p2:

    namespace std {
      template <class Key, class Compare = less<Key>,
        class Allocator = allocator<Key> > {
      class multiset {
      public:
        [.]
        multiset(initializer_list<value_type>,
          const Compare& = Compare(),
          const Allocator& = Allocator());
        template <class InputIterator>
        multiset(InputIterator first, InputIterator last, const Allocator& a)
          : multiset(first, last, Compare(), a) { }
        multiset(initializer_list<value_type> il, const Allocator& a)
          : multiset(il, Compare(), a) { }
        ~multiset();
        [.]
      };
    }
    
  14. Add to the synopsis in 23.5.4.1 [unord.map.overview] p3:

    namespace std {
      template <class Key, class T,
        class Hash = hash<Key>,
        class Pred = std::equal_to<Key>,
        class Allocator = std::allocator<std::pair<const Key, T> > > {
      class unordered_map {
      public:
        [.]
        unordered_map(initializer_list<value_type>,
          size_type = see below,
          const hasher& hf = hasher(),
          const key_equal& eql = key_equal(),
          const allocator_type& a = allocator_type());
        unordered_map(size_type n, const allocator_type& a)
          : unordered_map(n, hasher(), key_equal(), a) { }
        unordered_map(size_type n, const hasher& hf, const allocator_type& a)
          : unordered_map(n, hf, key_equal(), a) { }
        template <class InputIterator>
          unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
          : unordered_map(f, l, n, hasher(), key_equal(), a) { }
        template <class InputIterator>
          unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
    	    const allocator_type& a)
          : unordered_map(f, l, n, hf, key_equal(), a) { }
        unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
          : unordered_map(il, n, hasher(), key_equal(), a) { }
        unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, 
    	  const allocator_type& a)
          : unordered_map(il, n, hf, key_equal(), a) { }
        ~unordered_map();
        [.]
      };
    }
    
  15. Add to the synopsis in 23.5.5.1 [unord.multimap.overview] p3:

    namespace std {
      template <class Key, class T,
        class Hash = hash<Key>,
        class Pred = std::equal_to<Key>,
        class Allocator = std::allocator<std::pair<const Key, T> > > {
      class unordered_multimap {
      public:
        [.]
        unordered_multimap(initializer_list<value_type>,
          size_type = see below,
          const hasher& hf = hasher(),
          const key_equal& eql = key_equal(),
          const allocator_type& a = allocator_type());
        unordered_multimap(size_type n, const allocator_type& a)
          : unordered_multimap(n, hasher(), key_equal(), a) { }
        unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
          : unordered_multimap(n, hf, key_equal(), a) { }
        template <class InputIterator>
          unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
          : unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
        template <class InputIterator>
          unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
    	    const allocator_type& a)
          : unordered_multimap(f, l, n, hf, key_equal(), a) { }
        unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
          : unordered_multimap(il, n, hasher(), key_equal(), a) { }
        unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, 
    	  const allocator_type& a)
          : unordered_multimap(il, n, hf, key_equal(), a) { }
        ~unordered_multimap();
        [.]
      };
    }
    
  16. Add to the synopsis in 23.5.6.1 [unord.set.overview] p3:

    namespace std {
      template <class Key,
        class Hash = hash<Key>,
        class Pred = std::equal_to<Key>,
        class Allocator = std::allocator<Key> > {
      class unordered_set {
      public:
        [.]
        unordered_set(initializer_list<value_type>,
          size_type = see below,
          const hasher& hf = hasher(),
          const key_equal& eql = key_equal(),
          const allocator_type& a = allocator_type());
        unordered_set(size_type n, const allocator_type& a)
          : unordered_set(n, hasher(), key_equal(), a) { }
        unordered_set(size_type n, const hasher& hf, const allocator_type& a)
          : unordered_set(n, hf, key_equal(), a) { }
        template <class InputIterator>
          unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
          : unordered_set(f, l, n, hasher(), key_equal(), a) { }
        template <class InputIterator>
          unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
    	    const allocator_type& a)
          : unordered_set(f, l, n, hf, key_equal(), a) { }
        unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
          : unordered_set(il, n, hasher(), key_equal(), a) { }
        unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf, 
    	  const allocator_type& a)
          : unordered_set(il, n, hf, key_equal(), a) { }
        ~unordered_set();
        [.]
      };
    }
    
  17. Add to the synopsis in 23.5.7.1 [unord.multiset.overview] p3:

    namespace std {
      template <class Key,
        class Hash = hash<Key>,
        class Pred = std::equal_to<Key>,
        class Allocator = std::allocator<Key> > {
      class unordered_multiset {
      public:
        [.]
        unordered_multiset(initializer_list<value_type>,
          size_type = see below,
          const hasher& hf = hasher(),
          const key_equal& eql = key_equal(),
          const allocator_type& a = allocator_type());
        unordered_multiset(size_type n, const allocator_type& a)
          : unordered_multiset(n, hasher(), key_equal(), a) { }
        unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
          : unordered_multiset(n, hf, key_equal(), a) { }
        template <class InputIterator>
          unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
          : unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
        template <class InputIterator>
          unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
    	    const allocator_type& a)
          : unordered_multiset(f, l, n, hf, key_equal(), a) { }
        unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
          : unordered_multiset(il, n, hasher(), key_equal(), a) { }
        unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf, 
    	  const allocator_type& a)
          : unordered_multiset(il, n, hf, key_equal(), a) { }
        ~unordered_multiset();
        [.]
      };
    }
    

2229. Standard code conversion facets underspecified

In [locale.stdcvt] paragraph 2, Header codecvt synopsis:

template<class Elem, unsigned long Maxcode = 0x10ffff,
  codecvt_mode Mode = (codecvt_mode)0>
class codecvt_utf8
  : public codecvt<Elem, char, mbstate_t> {
  // unspecified
public:
  explicit codecvt_utf8(size_t refs = 0);
  ~codecvt_utf8();
  };

template<class Elem, unsigned long Maxcode = 0x10ffff,
  codecvt_mode Mode = (codecvt_mode)0>
class codecvt_utf16
  : public codecvt<Elem, char, mbstate_t> {
  // unspecified
public:
  explicit codecvt_utf16(size_t refs = 0);
  ~codecvt_utf16();
  };

template<class Elem, unsigned long Maxcode = 0x10ffff,
  codecvt_mode Mode = (codecvt_mode)0>
class codecvt_utf8_utf16
  : public codecvt<Elem, char, mbstate_t> {
  // unspecified
public:
  explicit codecvt_utf8_utf16(size_t refs = 0);
  ~codecvt_utf8_utf16();
  };

2235. Undefined behavior without proper requirements on basic_string constructors

This wording is relative to N3485.

  1. Change 21.4.2 [string.cons]/6 as indicated:

    basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
    

    -6- Requires: s shall not be a null pointer and n < npospoints to an array of at least n elements of charT.

  2. Change 21.4.2 [string.cons]/8 as indicated:

    basic_string(const charT* s, const Allocator& a = Allocator());
    

    -8- Requires: s shall not be a null pointerpoints to an array of at least traits::length(s) + 1 elements of charT.