Class design

Design7 standards

=default/=delete, explicit, hidden friends, defaulted <=>.

The special-member toolkit: =default, =delete, explicit single-arg constructors, override/final, delegating constructors. Deleted copies become the way to spell entity types.

class Mixer {
public:
  explicit Mixer(Config c);
  Mixer(const Mixer&) = delete;
  Mixer& operator=(const Mixer&) = delete;
  Mixer(Mixer&&) noexcept = default;
  ~Mixer() override;                 // override checked by compiler
};

No structural change — C++14 is a defect-fix release for class authors; deprecated attribute helps API evolution.

The hidden-friend idiom becomes standard practice: define operators as friends inside the class so they are found only by ADL, shrinking overload sets and improving errors. [[nodiscard]] guards factories.

class Price {
  friend bool operator==(Price a, Price b)   // hidden friend
  { return a.cents_ == b.cents_; }
  long long cents_;
public:
  [[nodiscard]] static Price from_cents(long long c);
};

Comparison boilerplate dies: default <=> (and ==). explicit(bool) makes conditionally-explicit wrappers writable; [[no_unique_address]] stores empty policies for free.

struct Extent {
  int w{}, h{};
  friend auto operator<=>(const Extent&, const Extent&) = default;
};
template <class T, class Alloc>
class Box {
  [[no_unique_address]] Alloc alloc_;   // zero bytes if empty
};

Deducing this collapses const/ref-qualified getter quartets into one template and enables CRTP-free mixins; static operator() makes stateless function objects honest.

struct Builder {
  template <class Self>
  Self&& with_title(this Self&& self, std::string t)   // chainable, no CRTP
  { self.title_ = std::move(t); return std::forward<Self>(self); }
};

= delete("reason") documents the why at the call site, contracts (pre/post) move preconditions out of comments, and reflection starts generating the remaining boilerplate.

void use(Session&) = delete("Session is single-owner: pass by value");

int pop() pre(!empty()) post(r : r >= 0);   // contracts, C++26
C++29direction · not adopted

Direction: reflection-based code generation (token injection, P3294 line of work) targets generating members, not just reading them — the end of hand-written builders and bindings.

C++26 per the final working draft; C++29 rows are proposals and direction, not adopted features.