// Usage: std::cout << " "_join("Hello", "World") << std::endl; #include #include #include #include class Joinit { public: Joinit(std::string_view sv): join(sv) {} template auto operator()(Args&&... args) { auto svs = std::make_tuple(std::string_view{std::forward(args)}...); auto len = [](auto... args){ return (args.length() + ...);}; std::string buffer; buffer.reserve(std::apply(len, svs)); auto joined_string = [&](auto... args){ return concat(buffer, args...); }; return std::apply(joined_string, svs); } private: auto& concat(std::string& str, std::string_view sv) { return str += sv; } template auto& concat(std::string& str, std::string_view sv, Args... args) { return concat(str.append(sv).append(this->join), args...); } std::string join; }; auto operator"" _join(const char* buffer, size_t size) { return Joinit{{buffer, size}}; }