Hi, Am 24.01.2017 11:52, schrieb Hans Dembinski:
Would you prefer str(), or implicit conversion?
Please, no implicit conversion. I don't like .str() but it is better than implicit conversion. Implicit conversion is confusing, especially in the context of templates and auto.
I didn't have good reasons, but this is in line with my gut feeling. I totally agree.
If format::hex<int> is allowed to be in any position and still affect the whole string, that is not at all intuitive.
My idea was to allow those formatting tags only at the beginning of the parameter list. Then separator("sadf") is just another formatting tag.
What happens when you have two conflicting formatting tags in the argument list? Which one wins?
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.
join(hex<int>, separator(" "), my_nums);
Here all the numbers are converted to their hex representation. With your approach this would look like:
join(separator(" "), my_nums | transform([](int i) -> int { return hex(i); }));
That is much more difficult to understand.
I don't see how that follows. You are free to write an overload for "join" which accepts an unary function as the first argument, which is then applied to all the values in the range. If hex<int> is an unary function, the first version makes even more sense.
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>()));
Still separator("...") is a bit out of the picture now. Up to mow I
thought, that it is some kind of formatting information and therefore I
handled it like other formatting tags. Actually I begin to like the idea
of formatting functions, that return string factories. That fits very
nicely with the rest of the API and makes concat(), join() and format()
simpler.
A completely different approach, inspired by Python:
separator(" ").join(my_nums | hex<int>());
Then we add free functions like this:
template The second version I reject regardless, because it uses an overloaded
operator |. That is the adaptor API from boost::range and is the same in ranges::v3.
It's not my invention.
Christof