Я пытаюсь написать функцию AsString (), которая преобразует контейнеры STL в строку по своему вкусу.Вот код, который я придумала до сих пор:
template<class T>
inline string AsString(const T& v);
template<class First, class Second>
inline string AsString(const pair<First, Second>& p);
template<class Iter>
inline string PrintSequence(const char* delimiters, Iter begin, Iter end) {
string result;
result += delimiters[0];
int size = 0;
for (size = 0; begin != end; ++size, ++begin) {
if (size > 0) {
result += ", ";
}
result += AsString(*begin);
}
result += delimiters[1];
result += StringPrintf("<%d>", size);
return result;
}
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
template<class T1, class T2> \
inline string AsString(const Sequence<T1, T2>& seq) { \
return PrintSequence("[]", seq.begin(), seq.end()); \
}
OUTPUT_TWO_ARG_CONTAINER(vector)
OUTPUT_TWO_ARG_CONTAINER(deque)
OUTPUT_TWO_ARG_CONTAINER(list)
template<class First, class Second>
inline string AsString(const pair<First, Second>& p) {
return "(" + AsString(p.first) + ", " + AsString(p.second) + ")";
}
template<class T>
inline string AsString(const T& v) {
ostringstream s;
s << v;
return s.str();
}
Как видите, основная идея заключается в том, что AsString()
рекурсивно вызывает себя в контейнерах STL, а затем переходит к обычному operator<<()
(причина, по которой я не хочу переопределять operator<<()
, заключается в том, что я не хочу вмешиваться в другие библиотеки, которые делают именно это).
Теперь AsString()
компилируется и работает на мелких контейнерах,но не для вложенных:
vector<int> v;
v.push_back(1);
v.push_back(2);
AsString(v) == "[1, 2]<2>"; // true
vector<vector<int> > m;
m.push_back(v);
m.push_back(v);
AsString(m) == "[[1, 2]<2>, [1, 2]<2>]<2>"; // Compilation Error!!!
Компилятор по какой-то причине хочет использовать operator<<()
при попытке печати элементов `m ', несмотря на то, что я предоставил специализацию шаблона длявекторы.
Как я могу заставить AsString()
работать?
ОБНОВЛЕНИЕ : ОК, оказывается, порядок определений имеет значение (по крайней мере, для этого компилятора - gcc4.4.3).Когда я сначала добавлю определения макросов, компилятор правильно их подберет и отобразит вектор векторов.Необъяснимые.