Hi, Am 24.01.2017 17:27, schrieb Hans Dembinski:
On 24 Jan 2017, at 12:54, Christof Donat
wrote: I think, that composes less elegantly with boost::range or ranges::v3. Maybe we could lean towards their adaptor APIs like this: join(separator(" "), my_nums | hex<int>()));
If you use the design with the unary function in the beginning, it works for boost::range and classic iterators. You can still compose several unary functions by using a lambda.
Sure, but a lambda is still more noise than a list of range adaptors (in ranges::v3 they are called "views"). join(separator("\n"), my_bytes | hex<int>(fixed_size(2)) | view::chunk(16) | join(separator(" "))).str(); Here I have added another, new idea. When join is only called without a range, it returns a range view/adaptor, that expects to iterate over a range of ranges and will return a range of string factories. The above code would produce multiple lines with 16 hex representation of bytes each.
OK, here you made a point. In a specification I'd leave the behavior undefined. In an actual implementation I'd have the later ones overwrite the previous ones, because I expect that to be easy to implement. We could also try and prevent that with meta programming, but I think, that is not worth the effort. Leaving it unspecified in the specification, still leaves us the option to do that later.
If you can catch the error it at compile time, so that it costs nothing at runtime, it is certainly worth the effort.
The issue is, that doing that is a lot of work. If we really want to do stuff and not just talk about, what could possibly be done, I'd propose to not implement it in the first release, but keep the behavior undefined in the specification, so that it can be implemented later.
A completely different approach, inspired by Python:
separator(" ").join(my_nums | hex<int>());
-1. It looks artificial in C++. In Python it is okay, because it creates a nice symmetry with .split(…). Here, there is no symmetry with .split. And any case, both should be methods of std::string then. For a user it will feel quite arbitrary that he/she has do use separator(" ").join(…) and instead of the simpler std::string(" ").join(…).
The latter is, in my opinion, even worse, because I really think, std::string should not have many member functions. But yes, the syntax I proposed here is not really intuitive in C++. Let's just forget about it. Christof