This is a very useful methodology. There's a similar blog post called "parse, don't validate" [1] which is very good.
[1] https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...
So, every time you create a UserName, it does those checks even if it doesn't need to? That doesn't sound very performant to me.
Interesting, I haven't thought about using it in C++ before.
It's an idea that has existed for a long time in languages geared toward safety-critical systems.
E.g. Derived Types in Ada: https://fsharpforfunandprofit.com/posts/designing-with-types...
It is sometimes used in Ocaml or F# for domain-specific types: https://fsharpforfunandprofit.com/posts/discriminated-unions...