1

C++ で未指定の型を取る循環バッファーを実装するように依頼されました。ジェネリック型はプリミティブ型であると想定しています。(または、非プリミティブ型を考慮する必要がありますか?) バッファーの場合、基本的な配列を使用しています。たとえば、T[]newおよびdeleteを使用して、初期化と破棄を行います。

バッファ クラスを実装し、予想される出力で整数に対してテストしました。しかし、それは動作しませんstd::string。問題は、バッファーをポップするときに要素をゼロに設定してクリアすると、コンパイラーがそうすることがあいまいであると不平を言うことです。そのため、要素をクリアするための一般的な方法が必要であり、std::arrayこの機能がサポートされている可能性があると考えていましたが、ドキュメントで見つけることができません。

std::array または基本配列の要素をクリアする一般的な方法はありますか、それとも std::allocator が私の唯一のオプションですか? または、完全に間違った方向に進んでいる場合、 pop メソッドを実装して最初の要素をリセットし、フロント インデックスを次の要素のインデックスにインクリメントする方法を教えてください。

前もって感謝します!

それが役立つ場合、以下は私の関連コードです:

template<class T> T CircularBuffer<T>::pop_front()
{
    if (_size == 0)
        return 0;
    T value = buffer[_front];
    buffer[_front] = 0;
    if (--_size == 0)
    {
        _front = -1;
        _back = -1;
    }
    else
    {
        _front = (_front + 1) % _capacity;
    }
    return value;
}
4

2 に答える 2

2

循環バッファでは、実際にはメモリから要素を削除しません。それ以外の場合は、Jagannath が指摘したように、std::dequeがオプションです。ポップされた要素を「リセット」するのが好きです。

buffer[_front] = 0;

は「に割り当てる」0を意味しTます。T = std::stringあいまいさを説明するためにそれを行う2つの方法があります。少し単純化すると、次のようになります。

std::string std::string::operator=(char c);

std::string std::string::operator=(const char *cPtr);

私はあなたがこれを望んでいないと思うので、私の選択は(TCが書いたように):

buffer[_front] = T();

さらに(非常に似た理由で)

if (_size == 0)
    return 0;

クラッシュするため、これも問題です。これを見てください:

std::string a = circularBuffer.pop_front(); // crashes on empty buffer

ここでもでき ますreturn T()が、よりクリーンな方法は確かにstd::out_of_range例外をスローすることです。

于 2015-05-04T09:42:23.890 に答える