私の好みに合わせてSTLコンテナを文字列に変換するAsString()関数を記述しようとしています。ここで私は、これまでに作ってみたコードです:あなたが見ることができるようにC++でSTLコンテナを印刷するための再帰的なAsString()
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!!!
コンパイラは、何らかの理由で、 `M」の要素を印刷しようとしたときにもかかわらず、operator<<()
を使用したいです私はベクトルのためのテンプレートの特殊化を提供しているという事実です。
どうすればAsString()
を動作させることができますか?
UPDATE:OK、定義の順序は問題ありません(少なくともこのコンパイラでは - gcc 4.4.3)。マクロ定義を最初に置くと、コンパイラはそれらを正しくピックアップし、ベクトルのベクトルを表示します。不可解。
マイナー発言:後でなくコンテナの前にサイズを入れておくと、再解析が簡単になります。そうでなければきちんとしたコード(テンプレート関数の 'inline'を削除するだけです)は不要です。 –