1

I have a container called "ntuple" that is essentially a C array and length. It's main purpose is to be the argument of multi-dimensional math functions. As of now, it's really fast and utilizes several constructors of the form

ntuple(double x, double y, double z)
{
    size = 3;
    vec = new double[size];
    vec[0] = x;
    vec[1] = y;
    vec[2] = z;
}

And every time I work with a higher dimensional, yet known function, I just add a new constructor. I have on for an array as well:

ntuple(double* invec, long unsigned insizesize)

In order to make my code more compatible with regular c++ code, should I implement an ntuple iterator class? Nothing I've done has needed one and it seems like it will just slow everything down. But the more I read, the more vital it seems to use iterators for the sake of compatibility with standard C++ code.

I worry that when someone tries to work with my code, it won't mesh well with the standard techniques that they expect to use. But the purpose of my ntuple class is just to take arguments into functions.

Should I implement the iterators just as a precaution (if someone else will try to use the STL on it) at the cost of slowing my code?

Thanks.

4

2 に答える 2

5

C 配列のラッパーにイテレータを実装するのは簡単です。 と の最初の要素と最後の 1 つ前の要素へのポインタをそれぞれ返すだけで、beginend仮想メソッドを POD クラスに追加してもそれほど遅くはなりません。何の。これらのメソッドによる配列へのアクセスは、配列インデックス ルックアップを使用するよりも遅くはなく、一部のコンテキストでは高速になる可能性があります。それらを使用しなくても、コードの実行速度が低下することはありません。

利点として、C++ 11 ではbeginandendメソッドがあり、std::beginそれstd::endを見つけて、for( auto x: container ) { /* code */ }型で動作する場合。

これは X/Y の問題のように思われるので、あなたの問題の 1 つは、ntupleクラスをまったく使用してはならないことだと思います。 std::vector<double>は、適切に記述された C スタイルの配列の薄いラッパーです。コピーするコストなしで渡すには、std::vector<double> const&.

余談ですが、STL は のテンプレート コンポーネントstdが派生したライブラリを参照します。stdいくつかの点でライブラリとは少し異なります。

于 2013-05-18T21:34:23.633 に答える
0

はい、ベクトルを使用しますが、(メモリに大量のデータがある場合) ベクトルのメモリの管理には十分注意してください。次に、実際にはこの 4 バイトのオーバーヘッドが発生します (容量が無駄になります)。

  • 常に明示的なサイズでベクトルを作成するか、空を作成して resize() を使用します
  • インデックスを使用してベクトルを塗りつぶします (vec[0] = ... のように)
  • push_back は絶対に使用しないでください - 必要以上の (2 倍の) メモリを要求する可能性があります

次のように、継承ベクトルを使用してこのルールを適用することもできます (ただし、この方法は推奨されない場合があります)。

class ntuple: public std::vector<double> {
private:
    typedef std::vector<double> super;
    void push_back(double); // do not implement
    // also forbid pop_back()
public:
    ntuble(double a, double b) {
      resize(2);
      (*this)[0] = a;
      (*this)[1] = b;
    }
    ntuple(double* invec, long unsigned size)
      : super(invec, invec + size)
    {
    }
    // all your other convenient constructors here
};

イテレータは引き続き begin() および end() メソッドでアクセスできます

于 2013-05-18T22:16:31.480 に答える