This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Open status.

### 3161. Container adapters mandate use of `emplace_back` but don't require it

Section: 24.6.8 [stack], 24.6.6 [queue] Status: Open Submitter: Marshall Clow Opened: 2018-10-02 Last modified: 2020-05-09

Priority: 3

View all other issues in [stack].

View all issues with Open status.

Discussion:

24.6.8 [stack] p1 says:

> Any sequence container supporting operations `back()`, `push_back()` and `pop_back()` can be used to instantiate `stack`.

but then in 24.6.8.2 [stack.defn] we have the following code:

    template<class... Args>
      decltype(auto) emplace(Args&&... args)
        { return c.emplace_back(std::forward<Args>(args)...); }

The same pattern appears in 24.6.6 [queue].

I see two ways to resolve this:

The first is to add `emplace_back()` to the list of requirements for underlying containers for `stack` and `queue`

The second is to replace the calls to `c.emplace_back(std::forward<Args>(args)...)` with `c.emplace(c.end(), std::forward<Args>(args)...)`. We can do this w/o messing with the list above because `emplace` is part of the sequence container requirements, while `emplace_back` is not. I checked the libc++ implementation of `vector`, `deque`, and `list`, and they all do the same thing for `emplace(end(), ...)` and `emplace_back(...)`.

[2019-02; Kona Wednesday night issue processing]

Status to Open; Casey to provide updated wording, and re-vote on reflector.

Polls were: NAD - 5-1-3; "Option B" - 2-5-2 and "Probe the container" - 7-2-0

Previous resolution [SUPERSEDED]:

> This wording is relative to N4762.

> > I have prepared two mutually exclusive options.
> > Option A a requirement for `emplace_back` to the underlying container.
> > Option B one replaces the calls to `emplace_back` with calls to `emplace`.

> Option A

> 1. Edit 24.6.8 [stack], as indicated:

>    Any sequence container supporting operations `back()`, `push_back()`, `emplace_back()` and `pop_back()` can be used to instantiate `stack`.

> 2. Edit 24.6.6.1 [queue.defn], as indicated:

>    Any sequence container supporting operations `front()`, `back()`, `push_back()`, `emplace_back()` and `pop_front()` can be used to instantiate `queue`.

> Option B

> 1. Edit 24.6.8.2 [stack.defn], class template `stack` definition, as indicated:

>    >     template<class... Args>
>    >       decltype(auto) emplace(Args&&... args)
>    >         { return c.emplace_back(c.end(), std::forward<Args>(args)...); }

> 2. Edit 24.6.6.1 [queue.defn], class template `queue` definition, as indicated:

>    >     template<class... Args>
>    >       decltype(auto) emplace(Args&&... args)
>    >         { return c.emplace_back(c.end(), std::forward<Args>(args)...); }

[2020-05 Casey provides new wording]

This is the "probe for `emplace_back` with fallback to `emplace`" approach that LWG wanted to see wording for in Kona.

[2020-05-09; Reflector prioritization]

Set priority to 3 after reflector discussions.

Proposed resolution:

This wording is relative to N4861.

1. Edit 24.6.8.2 [stack.defn], class template `stack` definition, as indicated:

   >     template<class... Args>
   >       decltype(auto) emplace(Args&&... args) {
   >         if constexpr (requires { c.emplace_back(std::forward<Args>(args)...); }) {
   >           return c.emplace_back(std::forward<Args>(args)...);
   >         } else {
   >           return c.emplace(c.end(), std::forward<Args>(args)...);
   >         }
   >       }

2. Edit 24.6.6.1 [queue.defn], class template `queue` definition, as indicated:

   >     template<class... Args>
   >       decltype(auto) emplace(Args&&... args) {
   >         if constexpr (requires { c.emplace_back(std::forward<Args>(args)...); }) {
   >           return c.emplace_back(std::forward<Args>(args)...);
   >         } else {
   >           return c.emplace(c.end(), std::forward<Args>(args)...);
   >         }
   >       }