[HN Gopher] What to do if you don't want a default constructor?
       ___________________________________________________________________
        
       What to do if you don't want a default constructor?
        
       Author : jandeboevrie
       Score  : 18 points
       Date   : 2024-07-18 06:10 UTC (2 days ago)
        
 (HTM) web link (www.sandordargo.com)
 (TXT) w3m dump (www.sandordargo.com)
        
       | comex wrote:
       | It's nice to make invalid states unrepresentable. Unfortunately,
       | you can't do that in C++ if you have a move constructor. C++
       | moves have to leave the source object in a valid state, since the
       | object can still be accessed afterwards and will still have its
       | destructor run. But unless your move is really just a copy, that
       | state has to be some kind of default, or at least semantically
       | meaningless. And if a valid but semantically meaningless state
       | exists, arguably you might as well use it for the default
       | constructor too.
        
         | masklinn wrote:
         | I don't think that argument holds much water.
         | 
         | A moved-from object needs to be in a valid state because the
         | destructor will still run, and so that needs to succeed (and
         | not UB).
         | 
         | Nobody ever says the moved-from state had to be useful or
         | recoverable from.
         | 
         | Alternatively, you can remove support for moving. That way the
         | moved-from issue disappears.
        
           | nemetroid wrote:
           | The standard library types are guaranteed to be in a useful
           | state after being moved from (the term "valid state" is used
           | for this). Of course, that doesn't mean that your own types
           | have to, but the C++ Core Guidelines suggest doing so [1].
           | 
           | 1: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelin
           | es...
        
             | forrestthewoods wrote:
             | I'm not sure I would say that "valid" and "useful" are the
             | same. Things that must be safe after moving: destructing,
             | assigning. No other operation need make sense.
             | 
             | It sucks that C++ can't enforce "don't use struct after
             | moving". It's definitely a wart, of which C++ has no
             | shortage. But you can still get away with no default
             | constructor and not having to sprinkle a kajillion
             | "isUseful" checks around your codebase.
             | 
             | Code can assume the struct is useful. The case where it's
             | not is rare and _probably_ won 't ever come up. Such is
             | life when writing C++!
        
               | nemetroid wrote:
               | > I'm not sure I would say that "valid" and "useful" are
               | the same.
               | 
               | In standardese, they are: an object in a "valid but
               | unspecified state" requires "that the object's invariants
               | are met and operations on the object behave as specified
               | for its type"[1]. In other words, any operation without
               | preconditions may be performed.
               | 
               | > Things that must be safe after moving: destructing,
               | assigning. No other operation need make sense.
               | 
               | That's not accurate _for standard library types_ : moved-
               | from objects must be in a "valid but unspecified
               | state"[2].
               | 
               | 1: C++23 working draft, 3.66 valid but unspecified state
               | [defns.valid]
               | 
               | 2: C++23 working draft, 16.4.6.15 Moved-from state of
               | library types [lib.types.movedfrom]
        
       | szundi wrote:
       | -O7 ?
        
       | masfuerte wrote:
       | operator<=> was new to me. It's the three-way comparison
       | operator.
       | 
       | https://en.cppreference.com/w/cpp/language/operator_comparis...
        
         | cpeterso wrote:
         | aka the spaceship operator. By defining just the spaceship
         | operator for some types A and B, the compiler can synthesize
         | overloads for the typical comparison operators like < <= == >=
         | > for A vs B and B vs A.
        
       ___________________________________________________________________
       (page generated 2024-07-20 23:04 UTC)