"Zero cost" is a pet peeve of mine. While I concede that the concept is useful, there is always a cost somewhere.
A very concrete example of this was a C++ unit test suite where templates were used to generate several combinations of tasks/backends for verification. At one point our cloud builders ran out of memory. To avoid upgrading the instances at a €€€ cost from all the abstraction, I did some manual type erasure.
So, zero cost typically only concerns run time characteristics. Even then there are elusive pitfalls, like generated code size.