回答:
std::array
が利用可能なC ++ 11 では、答えは「はい、配列は避けてください」です。C ++ 11より前のバージョンでは、C配列を使用して、自動ストレージ(つまり、スタック)に配列を割り当てる必要がある場合があります。
確かに、std::array
C ++ 11の場合でも、実際には静的データのみです。Cスタイルの配列には、次の3つの重要な利点があり
std::vector
ます。
動的割り当ては必要ありません。このため、非常に小さな配列が多数ある場合は、Cスタイルの配列が推奨されます。n次元の点のようなものを言います。
template <typename T, int dims>
class Point
{
T myData[dims];
// ...
};
通常、dims
は非常に小さく(2または3)、T
組み込み型(double
)であり、std::vector<Point>
何百万もの要素が含まれることになると
想像できます
。あなたは間違いなく3倍の数百万の動的割り当てを望んでいません。
静的初期化をサポートします。これは、次のような静的データの問題のみです。
struct Data { int i; char const* s; };
Data const ourData[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
これは、初期化のすべての順序の問題をstd::string
回避するため、ベクター(および)を使用するよりも望ましい場合がよくあります。実際のコードを実行する前に、データがプリロードされます。
最後に、上記に関連して、コンパイラは初期化子から配列の実際のサイズを計算できます。それらを数える必要はありません。
C ++ 11にアクセスできる場合はstd::array
、最初の2つの問題を解決し、最初のケースではCスタイルの配列よりも優先して使用する必要があります。ただし、3つ目については取り上げていません。また、コンパイラーに初期化子の数に従って配列の次元を指定させることは、Cスタイルの配列を好む正当な理由です。
int i[] = { 1, 2, 3 };
での作業を続行しint i[] = { 1, 2, 3, 4 };
ます。array<int, 3>
をに手動で変更する必要がありますarray<int, 4>
。
std::array
C ++ 11では[実際に静的データに対してのみ使用する]と答えています。
私は、動的メモリ割り当てを使用できない安全上重要なシステムに取り組んできました。メモリは常にスタック上にある必要があります。したがって、この場合、サイズはコンパイル時に固定されるため、配列を使用します。
std::array<T>
ましたが、スタックに割り当てられ、基本的に生の配列にオーバーヘッドはありません。
array
in c++
は、動的サイズstd::vector
との固定サイズ高速代替を提供しますstd::list
。std :: arrayは、の追加機能の1つですc++11
。Cスタイルの配列の集約型のセマンティクスを提供しながら、stdコンテナーの利点を提供します。
だからc++11
私は確かstd::array
にそれを必要とするところで、ベクトルよりも使うでしょう。しかし、私はCスタイルの配列を避けたいと思いC++03
ます。
ほとんどの場合、いいえ、生の配列を使用する理由は考えられませんvectors
。コードが新しい場合。
ライブラリが配列と生のポインタを期待するコードと互換性がある必要がある場合は、配列を使用する必要があるかもしれません。
vector.data()
C ++ 11 &vector.front()
以前。
静的な少量のデータを格納しているのであれば、配列は依然として有用だと思います。
std::vector
私が考えることができる以上の配列(もちろん、必要に応じて割り当て解除を自動的に管理する何かに包まれている)の唯一の利点は、vector
コンパイラがC ++ 11をサポートしてコンストラクタを移動しない限り、そのデータの所有権を渡すことができないことです。
swap
ます。
Cスタイルの配列は基本的なデータ構造であるため、使用した方がよい場合もあります。ただし、一般的なケースでは、基になるデータの隅を丸めるより高度なデータ構造を使用します。C ++を使用すると、メモリを使用して非常に興味深い便利な処理を実行できます。その多くは単純な配列で機能します。
std::array
s よりも基本的なのですか?多くの場合、両方とも同じアセンブリにコンパイルされます。
std::array
静的配列の上に構築されたセマンティクスを正確に定義しています。
内部でSTLコンテナーを使用する必要がありますが、異なるモジュール間でそのようなコンテナーへのポインターを渡してはなりません。そうしないと、依存関係が地獄になってしまいます。例:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
非常に良い解決策ですが、
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
その理由は、std :: stringはさまざまな方法で実装できますが、cスタイルの文字列は常にcスタイルの文字列だからです。