絶滅

どうでもいい

(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; 
}


こうして見ると"テンプレートのテンプレート"的なものが欲しくなるけど,そういう概念はあるのだろうか……