[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Detecting whether move semantics actually take place
From: |
Vadim Zeitlin |
Subject: |
Re: [lmi] Detecting whether move semantics actually take place |
Date: |
Wed, 3 Aug 2022 14:33:36 +0200 |
On Tue, 2 Aug 2022 00:33:55 +0000 Greg Chicares <gchicares@sbcglobal.net> wrote:
GC> On 7/23/22 15:41, Vadim Zeitlin wrote:
GC> [...]
GC> > First, and trivially, you should sprinkle magic constexpr dust all over
GC> > your code
GC>
GC> Done, in the second-oldest change here:
GC>
GC> origin/odd/move_semantics
GC> 4c41e5790 Expunge a semiotic nightmare
GC> cc46b95a1 Use 'concept' syntax
GC> f09746b48 Expand commentary
GC> 03e061cf6 Replace run-time with compile-time tests
GC> 2fbb26c9f Improve documentation
FWIW I've looked at these commits and didn't have anything to say about
them (except for remaining completely oblivious to "a Sable, c Bible"
remark in a comment, but I don't think it's materially important here).
GC> Right now I'm just staring at:
GC>
GC> struct can_copy
GC> {
GC> can_copy() = default;
GC> can_copy(can_copy const&) = default;
GC> can_copy(can_copy&&) = delete;
GC> can_copy& operator= (can_copy const&) = default;
GC> can_copy& operator= (can_copy&&) = delete;
GC> };
GC>
GC> can_copy a {};
GC> can_copy b {a}; // Looks copy-constructible to me.
GC> can_copy c = b; // And copy-assignable, too.
GC>
GC> static_assert(std::copyable<can_copy>);
You don't mention it, but this fails too, doesn't it? According to
https://en.cppreference.com/w/cpp/concepts/copyable it should because
copyable() implies movable(), which this class isn't.
GC> static_assert(std::copy_constructible<can_copy>); // fails
GC> static_assert(std::is_copy_constructible_v<can_copy>); // succeeds
GC>
GC> I do understand why they designed each of these predicates,
To be honest, I don't. So I just go directly to cppreference.com whenever
I need to use or understand the use of any of them.
GC> but including them all is embarrassing: they might at least
GC> have deprecated the name of the last one in favor of, say,
GC> "possesses_a_copy_constructor".
I do understand the constraints of backwards compatibility rather well
though...
GC> And I do understand the discussions that dismiss that example
GC> as bad code that should never be written. But that doesn't
GC> excuse the confusion caused by these two:
GC> copy_constructible
GC> is_copy_constructible
GC> having different meanings.
Maybe doesn't excuse, but I think at least a partial explanation of this
discrepancy is that is_copy_constructible() is pretty useless, as it can't
be relied on -- e.g. a class may have a copy ctor which ends up being
unusable. So I think the hope is/was for copy_constructible() to be more
useful in practice, but is_copy_constructible() is not useless, or at least
not harmful, enough to be deprecated neither. At least this is how I would
justify it if I had to.
Regards,
VZ
pgplkUs6nicPb.pgp
Description: PGP signature