(See the [previous iteration](https://codereview.stackexchange.com/questions/142902/simple-string-joiner-in-modern-c).)

Now, I have defined an iterator for dumping contents of a sequence such that the last element is not followed by the separator string.

**main.cpp**:


    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <sstream>
    #include <string>
    #include <vector>

    using std::cout;
    using std::endl;
    using std::for_each;
    using std::vector;

    using namespace std;

    template <typename T, typename charT=char, typename traits=char_traits<charT>>
    class my_ostream_iterator :
    public iterator<output_iterator_tag, void, void, void, void>
    {
        std::ostringstream* oss;
        std::string* separator;
        bool first_value_appended;

    public:

        my_ostream_iterator(std::ostringstream* oss_, std::string* separator_)
        :
        oss{oss_},
        separator{separator_},
        first_value_appended{false}
        {}

        my_ostream_iterator<T,charT,traits>& operator= (const T& value) {
            if (!first_value_appended)
            {
                *oss << value;
                first_value_appended = true;
            }
            else
            {
                *oss << *separator << value;
            }

            return *this;
        }

        my_ostream_iterator<T,charT,traits>& operator*()     { return *this; }
        my_ostream_iterator<T,charT,traits>& operator++()    { return *this; }
        my_ostream_iterator<T,charT,traits>& operator++(int) { return *this; }
    };

    template<typename InputIt>
    std::string join(InputIt begin,
                     InputIt end,
                     const std::string& separator =", ",
                     const std::string& concluder ="")
    {
        std::ostringstream ss;
        std::string sep = separator;
        using value_type = typename std::iterator_traits<InputIt>::value_type;

        std::copy(begin,
                  end,
                  my_ostream_iterator<value_type>(&ss, &sep));

        ss << concluder;
        return ss.str();
    }

    int main() {
        vector<vector<int>> matrix = {
            { 1, 2, 3 },
            { 4, 5 },
            { },
            { 10, 26, 29 }
        };

        for_each(matrix.cbegin(),
                 matrix.cend(),
                 [](std::vector<int> a) {
                     cout << join(a.cbegin(), a.cend()) << endl;
                 });
    }

As always, any critique is much appreciated.