1

限られた数のアイテムをコンテナに格納したい。不要なオブジェクト コンストラクターの呼び出しを避けたいので、配列を使用したくありません。std::vector暗黙的な呼び出しのため、使用したくありませんmalloc(最大のキャッシュ コヒーレンスのためにヒープへのアクセスを最小限に抑えたい)。

そこで、次のような独自のカスタム コンテナーを定義することにしました。

template<typename T, size_t capacity> class my_array {
  private:
   char buffer[sizeof(T)*capacity];
   ...
  public:
   T& operator[](size_t i) { return *(T*)&buffer[i*sizeof(A)]; }
   ...
};

しかし、実際にこのコンテナーを使用しようとすると、厳密なエイリアス規則に違反しているというコンパイラの警告が表示されます。厳密なエイリアシングについて読み、コンパイラの最適化によって上記のコードが壊れる理由を理解しました。

どうすればこれを回避できますか?

奇妙なことに、私のコンパイラーは私のカスタムobject_poolクラスについて何の不満も持っていません。特に、連想 STL データ構造のカスタム アロケーターとして使用しています。そのクラスは上記のものと非常によく似ています ( achar[]を使用し、同様のキャストを行います)。2つの違いが何であるかわかりません。

4

4 に答える 4

1

使用してstd::array ください。. . . . . . . . . . . . !

于 2013-03-22T00:18:54.200 に答える
1

std::aligned_storage必要に応じてオブジェクトを初期化したくない場合に使用しstd::arrayます。構造体が奇妙なアドレスに割り当てられている可能性があるため、アライメントの問題が発生する可能性があります。

配列をストレージとして使用するためのエイリアスはchar問題ありませんが、コンパイラが何をしているのかわかりません。それは本当に最小限のテストケースですか?

于 2013-03-22T00:34:58.480 に答える
0

object_pool元の投稿でほのめかしたクラスと正確に比較することで、不思議な解決策を見つけました。

交換しました

T& operator[](size_t i) { return *(T*)&buffer[i*sizeof(A)]; }

T* operator[](size_t i) {
  if (...) {
    return (T*)&buffer[i*sizeof(A)];
  }
  return NULL;
}

ここで、...は常に に評価されることがわかっている述語ですtrueが、コンパイラが認識できるほど賢くなく、常に に評価される述語ですtrue

ここでコンパイラの頭を通過していることを誰かが正確に説明できるかどうか知りたいです。gcc 4.4.3 を使用しています。

于 2013-03-22T15:27:01.430 に答える