汎用出力関数(?)
Posted: 2011年8月16日(火) 22:05
こんにちは。先ほど、unordered_set関連のトピックにてテンプレート特殊化について教わった者です。
どうもありがとうございました。
続けての投稿失礼します。
実は前々からpythonのprint関数のように、
1. printの中身が整数ならそのまま出力、
2. vector<int>なら[]とカンマで区切って順番に出力
3. vector<vector<int> >なら[[, ],[, ] ,[, ] ]のように入れ子にして出力
といった関数がほしいと思っておりました。
テンプレート特殊化を用いることで以下のようにひとまずは実現できました。
カンマが最後についてしまってやや見苦しいですが、これは大した問題ではないので、ご容赦ください。
ついでに以下の関数はvector<int>であれ、set<int>であれ、list<vector<int> >みたいな形であれ出力してくれることでしょう!
しかしながら、未だに解決できないことがありまして、それは以下であります。
1. 「cout<<v」のようにostreamを指定することで出力されるようにしたい。
(下のコードの#define COMPROMISEをコメントアウトしていただければそれっぽいコードになりますが、コンパイルできません。。。)
2. 1. に関係しておりますが、「ostream &operator<<(ostream &os, T &x)」がすでにiostreamなどで定義されていればそれを使い、
そうでなければテンプレート関数から定義するようにしたい。
テンプレート特殊化と似ていますが、最初に定義されているテンプレートは除くという点で違いそれが解決できません。
3. vector<int>の出力の場合は"vector[1, 2, 3, 4]"とset<int>の場合は"set[1, 2, 3, 4]"といったように、
[]の前に型名を表示させたい。
__typeof指定子をstring型に渡すような関数があれば実現できると思ったのですが・・・
この3点のうち一つでも構いませんのでご存知の方はご教示いただけたら幸いです。
どうもありがとうございました。
続けての投稿失礼します。
実は前々からpythonのprint関数のように、
1. printの中身が整数ならそのまま出力、
2. vector<int>なら[]とカンマで区切って順番に出力
3. vector<vector<int> >なら[[, ],[, ] ,[, ] ]のように入れ子にして出力
といった関数がほしいと思っておりました。
テンプレート特殊化を用いることで以下のようにひとまずは実現できました。
カンマが最後についてしまってやや見苦しいですが、これは大した問題ではないので、ご容赦ください。
ついでに以下の関数はvector<int>であれ、set<int>であれ、list<vector<int> >みたいな形であれ出力してくれることでしょう!
しかしながら、未だに解決できないことがありまして、それは以下であります。
1. 「cout<<v」のようにostreamを指定することで出力されるようにしたい。
(下のコードの#define COMPROMISEをコメントアウトしていただければそれっぽいコードになりますが、コンパイルできません。。。)
2. 1. に関係しておりますが、「ostream &operator<<(ostream &os, T &x)」がすでにiostreamなどで定義されていればそれを使い、
そうでなければテンプレート関数から定義するようにしたい。
テンプレート特殊化と似ていますが、最初に定義されているテンプレートは除くという点で違いそれが解決できません。
3. vector<int>の出力の場合は"vector[1, 2, 3, 4]"とset<int>の場合は"set[1, 2, 3, 4]"といったように、
[]の前に型名を表示させたい。
__typeof指定子をstring型に渡すような関数があれば実現できると思ったのですが・・・
この3点のうち一つでも構いませんのでご存知の方はご教示いただけたら幸いです。
#include<iostream>
#include<vector>
using namespace std;
#define COMPROMISE
#ifndef COMPROMISE
template<class T>
ostream &operator<<(ostream &os, T &x) {
os<<"[";
for(__typeof(x.begin()) it=x.begin();it!=x.end();it++){
os<<*it<<",";
}
os<<"]";
return os;
}
template<>
ostream &operator<<(ostream &os, int &x) {
os<<x;
return os;
}
#else
template<class T>
void print(T &x) {
cout<<"[";
for(__typeof(x.begin()) it=x.begin();it!=x.end();it++){
print(*it);
cout<<",";
}
cout<<"]";
}
template<>
void print(int &x) { cout<<x;}
#endif
int main(){
vector<vector<int> > v(3,vector<int>());
v[0].push_back(1);v[0].push_back(2);v[0].push_back(3);
v[1].push_back(4);v[1].push_back(5);v[1].push_back(6); v[1].push_back(7);v[2].push_back(8);v[2].push_back(9);
#ifndef COMPROMISE
cout<<v;
#else
print(v);
#endif
return 0;
}