5

Visual Studio C++ 2010 ではbasic_string::append (iter, iter)、明らかに、std::copy.

最初の質問:

std::copyここで、より効率的なブロック単位のコピーを提供するために、最適化された反復子型のオーバーロードと共に、独自の反復子型を実装するとします。basic_string::appendオーバーロード以外にも、この最適化を利用する方法はありますappendか?

basic_string::append (iter, iter)文字ごとのコピーを行わない可能性はありますか?

2 番目の質問 (私自身の実装の出発点として):

以下は有効であることが保証されていますか?

std::string t ("JohnB");
std::string s;
s.reserve (10);
std::copy (t.begin (), t.end (), s.begin ());
s.push_back ('\0');

または私はより良いを使用する必要がありback_inserterますか?--を使用する場合、back_inserter文字単位のコピーを回避するにはどうすればよいですか?

4

2 に答える 2

5

文字列クラスには、含まれる文字に対して実行できる操作を定義する独自の特性クラスがあります。

charsをコピーするには、(より一般的な の代わりに)basic_string<char>を使用します。これはおそらく、標準 C ライブラリの関数にマップされます。std::char_traits<char>::copystd::copymemcpy

于 2012-11-26T23:26:35.353 に答える
2

の定義は、std::basic_string<cT, ...>::append()最終的にオーバーロードに到達する前に数回委任し続けます (21.4.6.2 [string::append] パラグラフ 7):

basic_string& append(const charT* s, size_type n);

この時点で、元のイテレータは明らかに残っていません。に渡した可能性のある入力イテレータに何が起こるか疑問に思っている場合append()は、同じ段落の段落 17 のオーバーロードによって削除されました。

効果: と同等append(basic_string(first, last))

ある中間状態で。標準ライブラリが標準で文字通りに述べられているように実装されている場合、明らかに呼び出しはありませんstd::copy()

std::copy()とにかく、オーバーロードされたバージョンを実際に見ることはできません。図書館ができることは、道徳的に同等です

template <typename InIt>
std::basic_string<cT, ...>& std::basic_string<cT, ...>::append(InIt begin, InIt end) {
    if (is_forward_iterator<begin>::value) {
        this->reserve(this->size() + std::distance(begin, end));
    }
    std::copy(begin, end, back_inserter_without_capacity_check<InIt>(*this);
}

さて、もう 1 つの興味深い点は次のとおりです。このように実装されたとしても、std::copy()! 部分的に特殊化することはできません(関数テンプレートを部分的に特殊化することはできません)。また、ターゲット イテレーターの型が定義されていません (上記の実装では、 ifがフォワード イテレーターstd::copy()の非容量チェック バリアントになり、そうでない場合は、と同じです。std::back_inserter()InItstd::back_inserter()

于 2012-11-26T23:36:59.823 に答える