In your case SetResolution could be a static method calling a private instance-method SetResolutionImpln, for example, similar to what other people said.
> what's the point of globally visible singletons except "everything is an object" cargo-culting?
Having the singleton be an object becomes interesting when:
1) it contains attributes that themselves have non-trivial constructors and/or destructors. Order of initialization and destruction is guaranteed (init is in forward order of declaration, destruction in reverse order)
2) more rarely, inheritance (code reuse)
In the case of 1), you can just opt to construct the singleton on a sufficiently-aligned byte buffer in-place with `std::construct_at`. This gets rid of static-init order fiasco, __cxa bloat (if applicable), atexit bloat, and you can chose to just not call `std::destroy_at` if you don't need to.
In these two scenarios it's a lot more efficient to group many related objects into a bigger object.
> what's the point of globally visible singletons except "everything is an object" cargo-culting?
Having the singleton be an object becomes interesting when:
1) it contains attributes that themselves have non-trivial constructors and/or destructors. Order of initialization and destruction is guaranteed (init is in forward order of declaration, destruction in reverse order)
2) more rarely, inheritance (code reuse)
In the case of 1), you can just opt to construct the singleton on a sufficiently-aligned byte buffer in-place with `std::construct_at`. This gets rid of static-init order fiasco, __cxa bloat (if applicable), atexit bloat, and you can chose to just not call `std::destroy_at` if you don't need to.
In these two scenarios it's a lot more efficient to group many related objects into a bigger object.