Make concrete types regular
Reason
Regular types are easier to understand and reason about than types that are not regular (irregularities require extra effort to understand and use).
The C++ built-in types are regular, and so are standard-library classes such as string, vector, and map. Concrete classes without assignment and equality can be defined, but they are (and should be) rare.
Example
struct Bundle {
string name;
vector<Record> vr;
};
bool operator==(const Bundle& a, const Bundle& b)
{
return a.name == b.name && a.vr == b.vr;
}
Bundle b1 { "my bundle", {r1, r2, r3}};
Bundle b2 = b1;
if (!(b1 == b2)) error("impossible!");
b2.name = "the other bundle";
if (b1 == b2) error("No!");
In particular, if a concrete type is copyable, prefer to also give it an equality comparison operator, and ensure that a = b implies a == b.
Note
For structs intended to be shared with C code, defining operator== may not be feasible.
Note
Handles for resources that cannot be cloned, e.g., a scoped_lock for a mutex, are concrete types but typically cannot be copied (instead, they can usually be moved), so they can't be regular; instead, they tend to be move-only.
Enforcement
???