The span for output is somewhat inflexible:

* it requires the caller to anticipate the number of results, and
* it requires contiguous storage, restricting the implementation.

It's probably better to make the function return an Input Range, enabling more flexible calling (e.g. I can then create a linked list of the results without overhead by using `std::ranges::copy(tokenize(…), std::back_inserter(my_list));`).

---
Without that change, I think it would be more useful to operate like `std::snprintf()` by returning the number of tokens that _would have_ been produced if the output range was large enough.  That allows callers to call again with a resized buffer if they need to.

---
I prefer the version with the range-based `for`, but that's probably irrelevant given that changes to the interface could well make that look completely different.