lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Various C++ m12ns


From: Vadim Zeitlin
Subject: Re: [lmi] Various C++ m12ns
Date: Mon, 6 Mar 2017 23:49:20 +0100

On Mon, 6 Mar 2017 22:28:53 +0000 Greg Chicares <address@hidden> wrote:

[...discussion of replacing lmi::uncopyable<> with "= delete" snipped...]

GC> Let's see if we can write a guideline for this....

 I did try to do this already earlier today, let me repost the link I had
posted in the "Define special member functions inline?" thread:

        https://gist.github.com/vadz/3222ef957769f3a9415caa799113d640

The relevant guideline is at the bottom.


GC> Declare these special member functions by default in every class X:
GC>     X(X const&) = delete;
GC>     X& operator=(X const&) = delete;
GC> If X should be Copyable, then use '= default' instead. Write implementations
GC> in '{}' only if the default does not do the right thing.
GC> 
GC> Rationale: In C++98, a comment such as
GC>   Implicitly-declared special member functions do the right thing
GC> was appropriate, with the declarations elided. But in C++11, it is
GC> preferable to say that in code. This is better than deriving from
GC> a noncopyable class because it is clearer and optimizes better.

 FWIW I do agree with this formulation, the trouble is that I wanted to be
more general and address all special member functions and not just the two
related to copyability.

GC> Already I have a question about the guideline. Would you also
GC> always declare a destructor, with '= default' by default?

 This is really the edge case, isn't it. I ended up by including the dtor
in my guideline at the link above too, but I'm not sure about it. On one
hand, it's consistent with the other special member functions. OTOH, a
non-default dtor should be very rarely needed in modern C++ code, where all
resources should be handled by the wrapper classes, so it seems
unnecessarily verbose to write "~X() = default" everywhere. Maybe it would
be better to omit it...

 OTOH I'm definitely for extending the same treatment to the default ctor,
i.e. writing "X() = default", even if it's unnecessary, because it
immediately shows that the class is default constructible, which might not
be obvious otherwise (contrast this with the dtor: all classes are
"destructible", so writing it explicitly doesn't provide any new
information).

GC> And another question. At first I was going to recommend either
GC>   public:
GC>     X(X const&) = default;
GC>     X& operator=(X const&) = default;
GC> or
GC>   private:
GC>     X(X const&) = delete;
GC>     X& operator=(X const&) = delete;
GC> but then I figured that calling a deleted public function ought
GC> to produce as clear a diagnostic as calling a deleted private one;

 Actually, it produces a more clear diagnostic: with the public deleted
function you get just an error about "use of deleted function", while with
a private one you get first several lines pertaining to "<function> is
private" before the same error as you'd get with the public one.

GC> so I think it's okay to declare these preferably in the neighborhood
GC> of other special-member-function declarations,

 Yes.

GC> but that seems to require no guideline.

 Yes.

GC> A private '= delete' declaration is never wrong, and I won't move the
GC> ones I've already written, but in the future I'd probably write all
GC> special member functions together in the typical case.

 And for the third time in a row I say yes. This must be some sort of a
record.

 Best regards,
VZ


reply via email to

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