The big problem (other than verbose code) with rolling up stuff into classes in C++ is that performance suffers. Many platforms will not pass small structs efficiently.
Inspired by Haskell's newtype, I drafted a proposal for C++14 which would have introduced native newtype to C++, but it got rolled into an omnibus paper (n3635) and appears to have been forgotten.
The proposal is modelled on strong enums, but generalizes them to all types. They are essentially strong typedefs with none of the weaknesses of wrapper types, restrict pointers, typedefs, and pragma disjoint.
newtype NotInt : int;
NotInt k(5); // call ‘default’
NotInt bar(NotInt);
bar(k); // passes exactly as an ABI int would
int baz(int&);
baz(k); // Error! no conversion
While drafting this proposal, I realized it was a much more C++-like way of bifurcating aliases than 'restrict' keyword: newtype D1 : double;
newtype D2 : double;
void biz(D1 *x, D2 *y) {
// Being separate, D1/D2 can be
// assumed not to alias by optimizers
...
}
While playing with it, we came up with this proposed syntax (although I don't think this would get through the committee): [template <typename T>]
newtype [NotT] : [(public|private)] T [= (default|explicit|deleted)] [{
// only non-virtual member functions, no data or reference members (something like POD)
// this->value has all of the operations of T, but only aliases with the new type, and implicitly converts to/from T prvalues.
}] [optional_variable_name];