I don't see how Boost algorithms provide the aliasing guarantees you need to avoid invalidating iterators. It's a very difficult problem. Even if you use a library to pipe instances of your custom string class to cout and you trust that library, the method or function that sends your custom string class to cout could perform arbitrary mutations, which would invalidate the iterator.
For example:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
class mystring {
public:
std::string m_s;
mystring(const std::string &s) : m_s(s) {}
};
std::vector<mystring> v;
void operator<<(std::ostream &out, const mystring &ms) {
v.clear();
out << ms.m_s;
}
int main() {
v.push_back(mystring(std::string("Hello")));
v.push_back(mystring(std::string("world")));
std::copy(v.begin(), v.end(), std::ostream_iterator<mystring>(std::cout, "\n"));
return 0;
}