1

Boost Rangesには、要素を簡単にカンマやスペースで区切るなどの方法が組み込まれていますか?

もちろん、それらをループして別々に印刷できることは承知していますが、これは何らかの方法で組み込む必要があるようです(スクリプト言語でベクトルを印刷するなど)。

私が見たサンプルプログラムでは、作者は範囲をcoutにコピーしました。

boost :: copy(range、ostream_iterator(cout、 ""))

私には醜いように見えます。これは慣用的ですか?

編集:stdイテレータのソリューションも受け入れられます。

EDIT2:私がやりたいことはこれです:

cout << range;

しかし、私はそれがうまくいくとは思いません。だから私が望んでいるのはこのようなものです(Pythonに触発されました):

cout << range.join(", ");

またはおそらくレンジアダプターを使用します。

cout << (range | stringify(", "));
4

2 に答える 2

4

本当に完成/磨かれたとは思いませんが、それがBoost.Exploreの目的です。

個人的には、を使用することに慣れたばかりstd::copyです。この種のことについては、infix_ostream_iterator時々非常に役立つことがあります。たとえば、次のようなものです。

#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
#include "infix_iterator.h"

template <typename T>
std::ostream& operator<<(std::ostream &o, const std::vector<T>& v) { 
    o << "[";
    std::copy(v.begin(), v.end(), infix_ostream_iterator<T>(o, ", ")); 
    o << "]";
    return o; 
}

int main() { 

    std::vector<int> x;

    for (int i=0; i<20; i+=2)
        x.push_back(i);

    std::cout << x << "\n";
    return 0;
}

現状では、これにはoperator<<ベクトルがありますが、代わりに範囲を取るのは比較的簡単です。

于 2012-04-04T16:57:48.890 に答える
1

前方反復可能範囲を出力する一般的な関数を定義することをお勧めします。これが私が使用したjoin()関数です:

template<typename ForwardIter>
std::string join(const ForwardIter& it1, const ForwardIter& it2, const std::string& separator=" ") {
    if(it1 != it2) {
        std::ostringstream s;
        s << *it1;
        for(ForwardIter i=it1+1; i!=it2; i++)  s << separator << *i;
        return s.str();
    }
    else return "";
}

template<typename Range>
std::string join(const Range& r, const std::string& separator=" ") { return join(r.begin(), r.end(), separator); }

この関数は文字列を返し、リスト、ベクトル、セットなど、各要素の間接参照をostreamによって個別に出力できる前方反復可能な範囲を取る必要があります。この関数を使用すると、次のように使用できます。

list<int> a = {1,2,3,4};
set<int> b = {4,3,2,1};
vector<int> c = {1,2,3,4};


cout << join(a) << endl;
cout << join(b, ",") << endl;
cout << join(c.begin(), c.begin()+2, "~") << endl;

join()名が名前空間と衝突する可能性があることを覚えているので、名前をjoiningやjointなどの同様の名前に変更することをお勧めします。また、boostを使用する場合は、互換性を高めるために、r.begin()の代わりにboost :: begin(r)を使用することをお勧めします。

于 2012-04-04T19:41:40.180 に答える