33

非常によく似た質問があります

glibcの文字列実装を使用してスタックにstd::stringを割り当てるにはどうすればよいですか?

しかし、もう一度尋ねる価値があると思います。

std::stringフリーストアにオーバーフローするローカルストレージを備えたものが必要です。std::basic_stringはテンプレートパラメータとしてアロケータを提供するので、ローカルストレージを使用してアロケータを作成し、それを使用して次のようにパラメータを設定する必要がbasic_stringあるようです。

std::basic_string<
char, 
std::char_traits<char>, 
inline_allocator<char, 10> 
> 
x("test");

inline_allocator期待どおりに機能するクラスを作成しようとしました。ストレージ用に10バイトを予約し、10バイトをbasic_string超える必要がある場合は、を呼び出します::operator new()。動作させることができませんでした。上記のコード行を実行する過程で、私のGCC4.5標準文字列ライブラリはコピーコンストラクターをinline_allocator4回呼び出します。のコピーコンストラクターを作成するための賢明な方法があるかどうかは私にはわかりませんinline_allocator

他のStackOverflowスレッドで、EricMelskiはChromiumのクラスへのこのリンクを提供しました。

http://src.chromium.org/svn/trunk/src/base/stack_container.h

これは興味深いですが、のドロップイン置換ではありません。これは、をコンテナstd::stringにラップするstd::basic_stringため、オーバーロードを呼び出して。operator->()に到達する必要があるためstd::basic_stringです。

この問題に対する他の解決策は見つかりません。良い解決策がないということでしょうか?そしてそれが本当なら、そしてstd::basic_string概念はstd::allocatorひどく欠陥がありますか?std::basic_stringつまり、これはとの非常に基本的で単純なユースケースである必要があるようstd::allocatorです。コンセプトstd::allocatorは主にプール向けに設計されていると思いますが、これもカバーする必要があると思います。

inline_allocator文字列ライブラリがbasic_stringコピーコンストラクタの代わりにアロケータの移動コンストラクタを使用するように書き直された場合、C++0xの右辺値参照の移動セマンティクスによって書き込みが可能になるようです。誰かがその結果の見通しが何であるか知っていますか?

私のアプリケーションは1秒あたり100万個の小さなASCII文字列を作成する必要があるため、に基づいて独自の固定長文字列クラスを作成するBoost.Arrayことになりました。これは正常に機能しますが、それでも気になります。

4

4 に答える 4

16

「ModernC++Design」を書いた、C++プログラマーの並外れたAndreiAlexandrescuは、カスタマイズ可能なストレージシステムを使用してさまざまな文字列実装を構築することについてのすばらしい記事を書いたことがあります。彼の記事(ここにリンクされています)では、あらゆる種類の巧妙なメモリ割り当て要件を処理できる、はるかに一般的なシステムの特殊なケースとして、上記で説明したことを実行する方法について説明しています。これはあまり話さずstd::string、完全にカスタマイズされた文字列クラスに焦点を当てていますが、実装にはいくつかの実際の宝石があるので、それを調べたいと思うかもしれません。

于 2011-03-30T22:52:02.007 に答える
10

C++2011は本当にここであなたを助けるつもりです:)

事実allocator、C++03の概念は機能していませんでした。要件の1つは、タイプのアロケータがタイプAの他のアロケータからメモリの割り当てを解除できる必要があることでしたA...残念ながら、この要件は、それぞれが独自のプールにフックされたステートフルアロケータとも相容れません。

ハワード・ヒナント(C ++委員会のSTLサブグループを管理し、C ++ 0x用に新しいSTLをゼロから実装している)は、彼のWebサイトでスタックベースのアロケータを調査しました。

于 2011-03-31T07:18:48.180 に答える
6

これは通常不要です。これは「短い文字列の最適化」と呼ばれ、のほとんどの実装にはstd::stringすでに含まれています。見つけるのは難しいかもしれませんが、とにかく通常はそこにあります。

たとえば、sso_string_base.hMinGWの一部である関連部分は次のとおりです。

  enum { _S_local_capacity = 15 };

  union
  {
_CharT           _M_local_data[_S_local_capacity + 1];
size_type        _M_allocated_capacity;
  };

メンバーは関連するものです。_M_local_dataヒープにスペースを割り当てずに、15文字(およびNULターミネーター)を格納するためのスペースです。

メモリが機能する場合、VC ++に含まれているDinkumwareライブラリは20文字のスペースを割り当てますが、私が見てからしばらく経っているので、それを誓うことはできません(そして、ヘッダー内の多くのものを追跡するのは苦痛になる傾向があります。できれば見ないほうがいいです)。

いずれにせよ、私はあなたが時期尚早の最適化として知られているその非常に人気のある通過時間に従事しているという良い確率を与えるでしょう。

于 2011-03-30T22:47:20.583 に答える
2

Chromiumのコードは、物事を素敵なシェルにラップしているだけだと思います。ただし、Chromiumラッパーコンテナを使用しなくても同じ効果を得ることができます。

アロケータオブジェクトは頻繁にコピーされるため、メモリへの参照またはポインタを保持する必要があります。したがって、必要なのは、ストレージバッファーを作成し、アロケーターオブジェクトを作成してから、アロケーターを使用してstd::stringコンストラクターを呼び出すことです。

ラッパークラスを使用するよりもはるかに言葉が多くなりますが、同じ効果が得られるはずです。

スタックベクトルについての私の質問で、冗長な方法(まだクロムのものを使用している)の例を見ることができます

于 2011-03-30T21:47:51.317 に答える