---
title: "Adjoints to \"Enabling list-initialization for algorithms\": uninitialized_fill"
document: P3787R2
date: 2026-03-24
audience: LEWG Library Evolution,LWG Library
reply-to:
  - "Giuseppe D'Angelo"
  - "Ruslan Arutyunyan"
paper-type: proposal
---

---

## Changelog

- R2 R1 Amended and rebased the wording in order to include the parallel range algorithms. R0 First submission
  - Fixed the wording after LWG review.

## Motivation and scope

In the Tokyo 2024 meeting [P2248R8] (Enabling list-initialization for algorithms) was adopted.

Due to an oversight, the `std::uninitialized_fill` family of algorithms was excluded from the ones where a defaulted template parameter was added.

We propose to modify `uninitialized_fill`’s specification, so that it matches the post-P2248 one for the rest of the algorithms (especially `fill`).

## Proposed Wording

All the proposed changes are relative to [N5032].

In [version.syn], bump the feature-test macro as shown:

```
#define __cpp_lib_algorithm_default_value_type 202403LYYYYMML
  // also in <algorithm>, <ranges>, <string>, <deque>, <list>, <forward_list>, <vector>, <memory>
```

where the new value corresponds to the year and month of adoption of the present proposal.

Note: [P3217R0] was also submitted as a similar fix for `find_last`. That proposal did **not** bump the feature-test macro, as it was considered a "hotfix". However, the time-frame is different for the present proposal: there are already implementations shipping with [P2248R8], and therefore we consider it safer to bump the value again.

---

Modify [memory.syn] and the corresponding signatures in the entries under [uninitialized.fill] as shown:

```
template<class NoThrowForwardIterator, class T = iterator_traits<NoThrowForwardIterator>::value_type>
  constexpr void uninitialized_fill(NoThrowForwardIterator first,                 // freestanding
                                    NoThrowForwardIterator last, const T& x);
template<class ExecutionPolicy, class NoThrowForwardIterator, class T = iterator_traits<NoThrowForwardIterator>::value_type>
  void uninitialized_fill(ExecutionPolicy&& exec,                         // freestanding-deleted,
                          NoThrowForwardIterator first,                   // see [algorithms.parallel.overloads]
                          NoThrowForwardIterator last,
                          const T& x);
template<class NoThrowForwardIterator, class Size, class T = iterator_traits<NoThrowForwardIterator>::value_type>
  constexpr NoThrowForwardIterator
    uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x);       // freestanding
template<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T = iterator_traits<NoThrowForwardIterator>::value_type>
  NoThrowForwardIterator
    uninitialized_fill_n(ExecutionPolicy&& exec,                          // freestanding-deleted,
                         NoThrowForwardIterator first,                    // see [algorithms.parallel.overloads]
                         Size n, const T& x);

namespace ranges {
  template<nothrow-forward-iterator I, nothrow-sentinel-for<I> S, class T = iter_value_t<I>>
    requires constructible_from<iter_value_t<I>, const T&>
      constexpr I uninitialized_fill(I first, S last, const T& x);                // freestanding
  template<nothrow-forward-range R, class T = range_value_t<R>>
    requires constructible_from<range_value_t<R>, const T&>
      constexpr borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x);     // freestanding

  template<nothrow-forward-iterator I, class T = iter_value_t<I>>
    requires constructible_from<iter_value_t<I>, const T&>
      constexpr I uninitialized_fill_n(I first,                                   // freestanding
                                       iter_difference_t<I> n, const T& x);

  template<execution-policy Ep, nothrow-random-access-iterator I,
           nothrow-sized-sentinel-for<I> S, class T = iter_value_t<I>>
    requires constructible_from<iter_value_t<I>, const T&>
      I uninitialized_fill(Ep&& exec, I first, S last, const T& x);       // freestanding-deleted,
                                                                          // see [algorithms.parallel.overloads]
  template<execution-policy Ep, nothrow-sized-random-access-range R, class T = range_value_t<R>>
    requires constructible_from<range_value_t<R>, const T&>
      borrowed_iterator_t<R> uninitialized_fill(Ep&& exec, R&& r,         // freestanding-deleted,
                                                const T& x);              // see [algorithms.parallel.overloads]

  template<execution-policy Ep, nothrow-random-access-iterator I, class T = iter_value_t<I>>
    requires constructible_from<iter_value_t<I>, const T&>
      I uninitialized_fill_n(Ep&& exec, I first,                          // freestanding-deleted,
                             iter_difference_t<I> n, const T& x);         // see [algorithms.parallel.overloads]
}
```

## Acknowledgements

Thanks to Ruslan Arutyunyan for spotting this oversight.

Thanks to KDAB for supporting this work.

All remaining errors are ours and ours only.

## References

### Informative References

**[N5032]
   Thomas Köppe. [Working Draft, Standard for Programming Language C++](https://wg21.link/n5032). 15 December 2025. URL: [https://wg21.link/n5032](https://wg21.link/n5032)
[P2248R8]
   Giuseppe D'Angelo. [Enabling list-initialization for algorithms](https://wg21.link/p2248r8). 20 March 2024. URL: [https://wg21.link/p2248r8](https://wg21.link/p2248r8)
[P3217R0]
   Giuseppe D'Angelo. [Adjoints to "Enabling list-initialization for algorithms": find_last](https://wg21.link/p3217r0). 20240331. URL: [https://wg21.link/p3217r0](https://wg21.link/p3217r0)**
