一般的な関数を定義して、繰返し可能な範囲を出力することができます。
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;
私はあなたがそのような参加や関節のような名前に名前を変更したい場合がありますので、参加する()名前は、いくつかの名前空間と衝突する可能性があることを覚えておいてください。また、ブーストを使用する場合は、より良い互換性のためにr.begin()の代わりにboost :: begin(r)を使用することもできます。
ありがとうございました。 STLとBoostが共通のコンテナにこれを定義していない理由は何ですか?私はこの方法について知っていたが(しかし、ブースト・エクスプローラについて聞いたことはない)、もっと慣用的な方法があるかもしれないときには、ちょっと汚い定義ヘルパー機能を感じる。 – Gurgeh
@Gurgeh:私は完全にはわかりません。完全に汎用化されていれば、文字列の入力や出力などの問題を「引き継ぐ」可能性があります。 –
それはあまり理由ではありません(もちろん、あなたのせいではありません)。通常の状況下では、オーバーロードされた演算子を正しい順序で解決することは困難ではありません。また、何かが間違っている可能性のあいまいなケースが一度もない場合は、標準コンテナごとに手動で定義することができます。とにかく、何か良いことが数時間で出てこないなら、あなたの答えを選びます。ディスカッションありがとう! – Gurgeh