Hi, Am 18.01.2017 10:59, schrieb Richard Hodges:
int main() { auto s= std::string("foo");
s = join("Hello ", ", World.", " The hex for ", 58, " is ", std::hex, 58); std::cout << s << std::endl;
s = join(separator(" : "), "a", "b", std::hex, 200 , std::quoted("banana")); std::cout << s << std::endl;
join(onto(s), separator(", "), "funky", "chicken"); join(onto(s), "====="); std::cout << s << std::endl; }
I do like the idea, but not the naming. With a function name "join" I'd expect to be able to pass an iterator range and have all its element concatenated into a string with a defined separator like this: auto my_number = std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; std::cout << join(std::begin(my_number), std::end(my_number), ", ") << std::endl; expected output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 maybe the name cat(), or concatenate() would fit better here. Also I am not 100% happy with is the reuse of iostream manipulators. They already don't have a distinct range of effect in iostream library. Another issue is, that the way, they work, is pretty complicated to be reused in a high performance implementation. How about an API like this: s = concat("Hello ", ", World.", " The hex for ", 58, " is ", concat_lib::hex(58)); s = concat(separator(" : "), "a", "b", concat_lib::hex(100), std::quoted("banana")); concat(onto(s), separator(", "), "funky", "chicken"); // will return a reference to s I guess concat(onto(s), "====="); This would go well with what I'd expect with the function name join(): s = join(std::begin(my_number), std::end(my_number)); // -> "12345678910" s = join(separator(", "), std::begin(my_number), std::end(my_number)); // -> "1, 2, 3, 4, 5, 6, 7, 8, 9, 10" join(onto(s), separator(" - "), std::begin(my_number), std::end(my_number)); // -> "1, 2, 3, 4, 5, 6, 7, 8, 9, 101 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10" Now, when we put it like that, there is no way, to let the functions "steal" work from each other. If you take this e.g.: concat(on(s), join(separator(", "), std::begin(my_number), std::end(my_number)), " ", join(separator(" - "), std::begin(my_number), std::end(my_number))); This will first execute the two join() calls that return strings, which are then passed to concat(). Instead join() and concat() could return objects, that can be converted to std::string. Then concat() can make the result of join() render its output into a common buffer. auto s = concat(join(separator(", "), std::begin(my_number), std::end(my_number)), " ", join(separator(" - "), std::begin(my_number), std::end(my_number))).str(); Christof