Hi, Am 23.01.2017 16:32, schrieb Hans Dembinski:
On 23 Jan 2017, at 11:23, Christof Donat
wrote: auto my_new_str = concat("Hello ", join(", ",std::begin(my_nums), std::end(my_nums)), format(" the file %1% contains %2% bytes", filename, filesize)).str(); It makes sense to me for "join" to return a string factory, because it is likely to be nested in "concat". But I don't see the practical case of nested "concat" calls, at least it is not going to be a common pattern in the need of optimising.
There is several usecases: 1. scope for formatting tags: concat(format::hex<int>, 42, " is hex for ", concat(42)).str(); Here the inner concat will convert the 42 to its decimal representation, while the outer one converts the first 42 to its hex representation. 2. concat() in calls to format(): format("%|1$40t|%2%", concat(first_name, " ", last_name), phone_number).str(); format().str() will allocate the buffer and ask the concat string factory to write into it. 3. results from concat() in a boost::range that is passed to join(): join(separator("\n"), my_files | transformed([](const std::filesystem::path& f) -> auto { return concat(f.filename, ": ", std::filesystem::file_size(f)); })).str(); join().str() will ask every concat string factory to render directly into the common buffer.
If "concat" is the outer layer anyway, I would return a std::string directly for convenience. It is easy to forget the trailing .str() and it does not look elegant.
Of course better proposals are welcome :-) Would you prefer the implicit conversion? If so, why? Christof