[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)