I think the author has left out a big piece why Rust enables better interface here: ownership. In C++ could the compile time checks prevent me from creating both an input and output type working on the same pin?
With template metaprogramming those invariants can be done at compile time.
It is a matter of type system design, the whole point of type-level programming.