(C++) std::vector に std::cout を拡張
何百番煎じか分かりませんが,まあまあ便利だし備忘録も兼ねて.
#include <iostream> #include <vector> using namespace std; template <typename _Ty> ostream& operator << (ostream& ostr, const vector<_Ty>& v) { if (v.empty()) { ostr << "{ }"; return ostr; } ostr << "{" << v.front(); for (auto itr = ++v.begin(); itr != v.end(); itr++) { ostr << ", " << *itr; } ostr << "}"; return ostr; } int main() { vector<int> vec(5, 1); // 1 を 5 個 vector< vector<int> > mat(5, vector<int>(5, 1)); // (1 を 5 個) を 5 個 cout << "vec = " << vec << endl; cout << "mat = " << mat << endl; return 0; }
出力結果
{1, 1, 1, 1, 1} {{1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}}
int じゃなくても出力用にシフト演算子がオーバーロードされてればなんでもいける.テンプレート関数やばい.
配列が何次元でもベクトルのベクトルの…のベクトル,という形のオブジェクトなら使えます.
(空白と改行じゃなくて中括弧多用してるのは Mathematica 先生にすぐ投げたかったから.)
おまけ:
vector に限らずイテレータのあるコンテナクラス(set, map とか)なら数行書き換えるだけで流用可能.
map
template <typename _KTy, typename _Ty> ostream& operator << (ostream& ostr, const pair<_KTy, _Ty>& m) { ostr << "{Key = " << m.first << ", " << "Value = " << m.second << "}"; return ostr; } template <typename _KTy, typename _Ty> ostream& operator << (ostream& ostr, const map<_KTy, _Ty>& m) { if (m.empty()) { ostr << "{ }"; return ostr; } ostr << "{" << *m.begin(); for (auto itr = ++m.begin(); itr != m.end(); itr++) { ostr << ", " << *itr; } ostr << "}"; return ostr; }
set
template <typename _Ty> ostream& operator << (ostream& ostr, const set<_Ty>& s) { if (s.empty()) ostr << "{ }"; return ostr; ostr << "{" << *(s.begin()); for (auto itr = ++s.begin(); itr != s.end(); itr++) ostr << ", " << *itr; ostr << "}"; return ostr; }
こうして見ると"テンプレートのテンプレート"的なものが欲しくなるけど,そういう概念はあるのだろうか……