I have a vector of strings with a size of 10. I want to join it to a string from index 3 to 6 with space as delimiter. I know boost::algorithm::join
could do it with the whole vector, but I want something that does it on a specific range with minimal copy and optimal efficiency. i know lot of stringstream based solution but i want something that doesn't have overhead of stringstream to string.
Asked
Active
Viewed 278 times
0

psyche
- 443
- 1
- 5
- 14
-
1possible duplicate of [How to implode a vector of strings into a string (the elegant way)](http://stackoverflow.com/questions/5689003/how-to-implode-a-vector-of-strings-into-a-string-the-elegant-way) – NathanOliver Aug 10 '15 at 14:01
-
not a duplicate i already read that question there is a solution for boost join given there for whole vec but I want to know if there is any inbuilt boost function for doing what i want – psyche Aug 10 '15 at 14:07
-
Well you don;t ask in your question for an inbuilt boost solution, you only state it is allowed. There are also other answers in that question that will do what you want and have O(n) efficiency which is as good as you can ask for. – NathanOliver Aug 10 '15 at 14:09
-
there are lot of copy creation and reallotcation going on in those solution so want to know if there is something that does not create unnecessary copy this is happening thousands of times in func so want as much efficiency as possible – psyche Aug 10 '15 at 14:12
2 Answers
2
You can create a range from something other than a complete container, and use boost::algorithm::join
just like in your original example.
#include <boost/algorithm/string/join.hpp>
#include <vector>
#include <iostream>
int main(int, char **)
{
std::vector<std::string> list;
list.push_back("Something");
list.push_back("that's");
list.push_back("not");
list.push_back("Hello");
list.push_back("World!");
list.push_back("really");
list.push_back("it's");
list.push_back("not");
boost::iterator_range<std::vector<std::string>::const_iterator>
rng (list.begin() + 3, list.begin() + 5);
std::string joined = boost::algorithm::join(rng, ", ");
std::cout << joined << std::endl;
}
still prints "Hello, World!"

Marshall Clow
- 15,972
- 2
- 29
- 45
1
As you need to reduce overhead I suggest to implement a custom version of std::back_insert_iterator
for std::string
.
So you might do this:
class my_back_insert_iterator :
public std::iterator<std::output_iterator_tag,void,void,void,void>
{
protected:
std::string* container;
public:
typedef std::string container_type;
explicit my_back_insert_iterator(std::string& x) : container(std::addressof(x)) {}
my_back_insert_iterator& operator=(const std::string& value)
{ container->append(value + " "); return *this; }
my_back_insert_iterator& operator=(std::string&& value)
{ container->append(std::move(value + " ")); return *this; }
my_back_insert_iterator& operator*()
{ return *this; }
my_back_insert_iterator& operator++()
{ return *this; }
my_back_insert_iterator& operator++(int)
{ return *this; }
};
After that you could easily do the following:
std::vector<std::string> strings = {"0", "1", "2", "3", "4",
"5", "6", "7", "8", "9"};
std::ptrdiff_t from = 3ULL;
std::ptrdiff_t to = 6ULL;
std::string joinedStrings;
std::move(strings.begin()+from, strings.begin()+to,
my_back_insert_iterator(joinedStrings));
joinedStrings += *(strings.begin()+to);
Try this online, too!
Old Answer
You could do the following:
std::vector<std::string> strings = {"0", "1", "2", "3", "4",
"5", "6", "7", "8", "9"};
std::ptrdiff_t from = 3ULL;
std::ptrdiff_t to = 6ULL;
std::stringstream ss;
std::copy(strings.begin()+from, strings.begin()+to,
std::ostream_iterator<std::string>(ss, " "));
ss << *(strings.begin()+to);
std::string joinedStrings = ss.str();
See it working online!

NaCl
- 2,683
- 2
- 23
- 37
-
I already use ostringstream for what i want to do but is there any thing possible so that copying could be reduced – psyche Aug 10 '15 at 14:08
-
@psyche You'll need to copy at least `to-from` elements and that's exactly what this does. `std::copy` does not access more than that. – NaCl Aug 10 '15 at 14:11
-
wont there be any overhead for ostringstream to string conversion??? this has to be done thousand of times so overhead minimization is what i require. – psyche Aug 10 '15 at 14:15