The downside there is you can still end up allocating a closure. Whereas an expanded macro shouldn't cost anything. (A sufficiently smart compiler might be able to optimize the closure allocation.)
A sufficiently modern language (like, saaaaay, D2) could also give you a type like "closure you don't intend to escape" (let's call this a "scoped closure", or if you will, "scope string delegate()"), and eschew allocation entirely without requiring optimization.