Вот эксперимент, который приведет вас к ответу:
#include <vector>
#include <ostream>
#include <iterator>
#include <algorithm>
#include <iostream>
namespace std {
template <template <typename...> class Container, class T>
std::ostream& operator<<(std::ostream& oss, const Container<T>& c) {
oss << "[";
std::copy(std::cbegin(c), std::prev(std::cend(c)), std::ostream_iterator<T>(oss, ","));
return oss << (*std::crbegin(c)) << "]";
}
}
int main() {
std::vector<unsigned> t{ 1, 2, 3 };
std::vector<std::vector<unsigned>> data(5, t);
std::cout << data << std::endl;
return 0;
}
Sidenote: без определения t
он скомпилируется (т. Е. Ваш operator<<
будет найден при необходимости), ноесли вы попытаетесь запустить его, он рухнет - попытка использовать std::prev(std::cend(c))
на пустом контейнере не закончится хорошо.
Конечно, это нарушает требования стандарта (определениеваше operator<<
внутри пространства имен std, как это не разрешено), но, по крайней мере, для типичных компиляторов теперь будет найдено имя, поэтому код будет скомпилирован.