On Sat, Nov 15, 2025 at 12:44 PM Jonathan Wakely via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Sat, 15 Nov 2025 at 06:33, Hewill Kang via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

In C++23, we can use `append_range` to append ranges to a container more intuitively and simply. Its function signature is as follows (from https://eel.is/c++draft/containers)
```
template<container-compatible-range<T> R>
  constexpr void append_range(R&& rg);
```
So we can:
```
std::vector<int> v;
v.append_range(std::views::iota(0, 5));
```

I think there are two areas for improvement.
First, it would be great to provide a default template to support `initializer_list`:

```
template<container-compatible-range<T> R = initializer_list<T>>
  constexpr void append_range(R&& rg);
```

which would make it more convenient for users:

```
std::vector<int> v;
v.append_range({1, 2, 3, 4});
```

How often do you want to append a hardcoded list of values though?
Initializer lists are useful for construction, when you often want to populate a container to a known set of values. I can't think of many times when I've wanted to append a known set of values to an existing container.
Maybe you would want to use it in a variadic function template to append a pack:
v.append_range({vals...});
But even that seems quite niche, and you can do:
v.append_range(std::initializer_list{vals...});

(`std::initializer_list<T>{vals...}`, that is, to avoid the pitfall of CTAD deducing the wrong type when T is a specialization of `initializer_list` and there's only one element in `vals`.)

This does seem somewhat in keeping with the direction of P2248 "Enabling list-initialization for algorithms," except that P2248 was only about permitting things like
    std::ranges::find(vector_of_pairs, {1,2})
and not things like
    std::ranges::set_intersection(vector_of_ints, {1,2,3})
. I thought there'd been a little discussion of the latter, but I don't see such discussion in P2248R8, anyway.


Additionally,  it might be more valuable if it could return `*this` instead of `void` [...]
which can provide a chain operation for users

Definitely not. That kind of "chaining" is essentially never useful in practice, and merely serves to (1) make the function's implementation one line longer and (2) make the codegen/register-pressure inside the function very marginally worse. It also leads to antipatterns on the caller side: it tempts users to write
    Object f(Object o) { return o.chained(); }  // makes a copy of `o`
as opposed to forcing the more efficient
    Object f(Object o) { o.chained(); return o; }  // moves from `o`
And, unless I'm mistaken, `.append_range` is part of the container requirements now, which means users will sometimes have to implement it themselves for their own containers. We must not force these infelicities and inefficiencies on them; we must at least allow them to write optimal code.

–Arthur