On Fri, Nov 10, 2023 at 11:20 PM Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
On Sat, 11 Nov 2023 at 01:01, Bryan Wong via Std-Discussion
<std-discussion@lists.isocpp.org> wrote:
>
> struct foo {
>     foo() = default;
>     foo(foo const&) = default;
>     foo& operator=(foo const&) = default;
>     foo(foo&&) = delete;
>     foo& operator=(foo&&) = delete;
> };

That type is an abomination. If you can copy a type, you can also move
it, and that just then does the same thing as copy if it can't move.
The standard library doesn't support types that are copyable but for
which move operations are ill-formed. Such types make
no sense, and appear only ever in testsuites.
 
 That's actually how I stumbled on the behaviour; I was writing up some test cases for a tuple-like implementation and this particular one failed. I was hesitant to call it a defect because I couldn't figure out a use case for such a type, but it also seems like it's breaking the principle of least surprise, so I thought I'd ask.

On Sat, Nov 11, 2023 at 2:53 AM Ville Voutilainen via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
On Sat, 11 Nov 2023 at 04:47, Jason McKesson via Std-Discussion
<std-discussion@lists.isocpp.org> wrote:
>
> On Fri, Nov 10, 2023 at 7:15 PM Ville Voutilainen
> <ville.voutilainen@gmail.com> wrote:
> >
> > On Sat, 11 Nov 2023 at 01:53, Jason McKesson via Std-Discussion
> > <std-discussion@lists.isocpp.org> wrote:
> >
> > > Yes, types like `tuple` *could* override the default behavior, but to
> > > be honest, it would be kind of weird for a C++ standard library
> > > aggregate type to behave so differently from a C++ language aggregate
> > > type. `tuple<not_null>` should behave the same as `container`.
> >
> > Tuple doesn't, it does override the "default" behavior, intentionally.
>
> It doesn't seem to. Link: https://gcc.godbolt.org/z/acrE8Mh9q
>
> That was the behavior I was talking about.

Cool, there's no difference here. There is a difference for certain
reference cases, because
tuple, being a non-aggregate, can't extend lifetimes like plain
aggregates do, so it chooses
to avoid cases that can cause immediate dangling. In such cases, tuple
might well copy
an object from an rvalue. If the type tries to make that ill-formed,
tuple will not care - intentionally.

I wasn't aware aggregates behave similarly as well, that's good to know.
Is it documented anywhere that the standard library doesn't support copyable-but-non-movable types? If not, do you think there's any benefit to adding it? Or do you think it's unnecessary as such types rarely make an appearance?  

--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion