lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] depr.impldec


From: Vadim Zeitlin
Subject: Re: [lmi] depr.impldec
Date: Tue, 12 Jul 2022 01:49:51 +0200

On Mon, 11 Jul 2022 22:47:11 +0000 Greg Chicares <gchicares@sbcglobal.net> 
wrote:

GC> On 7/11/22 21:55, Vadim Zeitlin wrote:
GC> > On Mon, 11 Jul 2022 19:28:50 +0000 Greg Chicares 
<gchicares@sbcglobal.net> wrote:
GC> > 
GC> > GC> On 7/10/22 12:29, Vadim Zeitlin wrote:
GC> > GC> [...]
GC> > GC> >  FWIW here is my personal strategy for defining the class' special
GC> > GC> > functions: there are several categories of classes
GC> > GC> > 
GC> > GC> > 1. Value-like: for them copy special functions and dtor are 
explicitly
GC> > GC> >    defaulted. Move special functions are omitted, and are not 
available.
GC> > GC> 
GC> > GC> Already I'm struggling here, but I think the issue is nomenclature.
GC> > GC> 
GC> > GC> Is this...
GC> > GC> 
GC> > GC> class custom_string
GC> > GC> {
GC> > GC>   public:
GC> > GC>     custom_string(std::string const& arg) : s_(arg) {}
GC> > GC>     custom_string() = default;
GC> > GC> 
GC> > GC>     custom_string& operator=(std::string const& arg) {s_ = arg; 
return *this;}
GC> > GC>     std::string const& value() const {return s_;}
GC> > GC> 
GC> > GC>   private:
GC> > GC>     std::string s_;
GC> > GC> };
GC> > GC> 
GC> > GC> a "value-like" class?
GC> > 
GC> >  Yes, it is, but it's also "container-like", where for me the difference 
is
GC> > that non-container values are cheap to copy while containers are not
GC> > necessarily. So for cheap to copy values move operations don't really
GC> > provide any gain, and can be omitted -- but can also be defaulted, as 
here.
GC> 
GC> I'm confused enough that, for now at least, I'm going to pay no attention
GC> to whether data members are cheap to copy, and focus on whether it's
GC> lawful to copy them. Cheapness is not a concept I can afford right now.

 But move semantics is mostly about optimizing copy, so discussing it
doesn't seem to make much sense if we don't care about the performance.

GC> I need a mental algorithm to decide what special members to default,
GC> delete, or not declare. Obviously whatever algorithm I was using was
GC> wrong, or has become wrong (or at least deprecated, which to me is wrong).
GC> I have a strong sense that a dominant input to this algorithm is the
GC> complexion of the class's data members (the nature of any base class is
GC> another, but for now I'm focusing on data members).

 I think the dominant input is whether the class has a non-trivial dtor. If
it does, it must mean that it manages some resources and then it certainly
needs to implement the 4 other special member functions as well.

GC> I'd like to have a generic name for a class that contains only
GC> whitelisted data members (ignoring base-class complications for now).
GC> There are so many names for so many concepts:
GC>   {trivial, POD, value-like, ...}
GC> and, if my idea is valid at all, someone must have devised a better
GC> name than class-for-which-all-defaulted-special-members-work-reliably.

 Unfortunately I don't know the name for this concept neither. It's
definitely _not_ is_trivially_destructible because this also requires the
members to be trivially destructible, which would exclude not only
unique_ptr<> (which might be warranted because its presence makes the class
non-copyable, so I don't think it should be included in your white list),
but also vector<>, which is clearly undesirable.

GC> Would you not use the Rule of Zero then? Class custom_string above
GC> seems almost perfect to me as is, and I think it would become less
GC> perfect if we added five explicitly defaulted members to it.

 I'm suspicious of the Rule of Zero because it just seems too fragile to
rely on the absence of something, so I prefer being explicit and defining
all the special member functions even if it's just to default them. I guess
I could live with a Rule of Zero combined with a prominent comment saying
that this class uses this rule, to exclude the possibility that the
required definitions (or deletions) were just forgotten. You probably can
ignore the danger of this happening in lmi, but in other C++ code bases,
with many people contributing to them, it's quite easy to let a class with
incorrect copying and/or moving semantics to slip in, so being explicit
about them feels (and, I think, is) much safer.

 FWIW I do use Rule of Zero for the structs, i.e. for the classes that
don't have any internal invariants but are just simple collections of data.
If custom_string were a struct (and I intentionally use struct keyword for
such classes), I wouldn't define any special functions for it.

 Regards,
VZ

Attachment: pgpMpNQZYUAGP.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]