On Tue, Jan 10, 2017 at 12:33 PM, Jonathan Wakely <jwak...@redhat.com> wrote:
> The standard says that the container adaptors have a constructor with
> a default argument, which serves as a default constructor. That
> involves default-constructing the underlying sequence as the default
> argument and then move-constructing the member variable from that
> argument. Because std::deque allocates memory in its move constructor
> this means the default constructor of an adaptor using std::deque
> will allocate twice, which is wasteful and expensive.
>
> This change adds a separate default constructor, defined as defaulted
> (and adding default member-initializers to ensure the member variables
> get value-initialized). This avoids the move-construction, so we only
> allocate once when using std::deque.
>

The new default member initializers use {}, and it's not too hard to find
test cases where {} and value-initialization do different things, including
cases where {} doesn't compile but () does. (So much for "uniform"
initialization.)

> Because the default constructor is defined as defaulted it will be
> deleted when the underlying sequence isn't default constructible,

That's not correct. There's no implicit deletion due to the presence of DMIs.
The reason the explicit instantiation works is that constructors explicitly
defaulted at their first declaration are not implicitly defined until ODR-used.

So, unlike the SFINAE-based approach outlined in the bugzilla issue, this
patch causes is_default_constructible<queue<T, NonDefaultConstructible>>
to trigger a hard error (though the standard's version isn't SFINAE-friendly
either).

Also, the change to .../priority_queue/requirements/explicit_instantiation/1.cc
adds a Cmp class but doesn't actually use it in the explicit instantiation.

Reply via email to