次のような非常に単純な配列を作成したい場合
int myArray[3] = {1,2,3};
std::array
代わりに使用する必要がありますか?
std::array<int, 3> a = {{1, 2, 3}};
std :: arrayを通常のものよりも使用する利点は何ですか?それはよりパフォーマンスが良いですか?コピー/アクセスの処理が簡単ですか?
次のような非常に単純な配列を作成したい場合
int myArray[3] = {1,2,3};
std::array
代わりに使用する必要がありますか?
std::array<int, 3> a = {{1, 2, 3}};
std :: arrayを通常のものよりも使用する利点は何ですか?それはよりパフォーマンスが良いですか?コピー/アクセスの処理が簡単ですか?
for (auto i = ++std::begin(myArray); . . .
コンパイルすらできない可能性があります(基本型のテンポラリは、少なくともclang 6では変更できないようです)
struct Direction { int32_t dw; int32_t dh; };
そしてstatic const Direction DIRECTIONS[DIRECTIONS_COUNT] { { -1, 1}, {0,1}, {1,1} , { 1, 0 }, {1,-1}, {0,-1} , {-1,-1}, {-1,0} };
コンパイルします。ただし、std::array<Direction,DIRECTIONS_COUNT>
同じ初期化子リストを使用してに変更すると、突然「初期化子が多すぎます」というエラーが発生します。(言語= C ++ 17とVS 2019コミュニティ)
std::array
初期化で二重角かっこを使用するのはなぜですか?
回答:
Astd::array
は、Cスタイルの配列の非常に薄いラッパーであり、基本的に次のように定義されます。
template<typename T, size_t N>
class array
{
public:
T _data[N];
T& operator[](size_t);
const T& operator[](size_t) const;
// other member functions and typedefs
};
これは集合体であり、基本的な型のように使用できます(つまり、値渡し、割り当てなどが可能ですが、標準のC配列を別の配列に直接割り当てたりコピーしたりすることはできません)。いくつかの標準実装(お気に入りのIDEから定義にジャンプするか、直接開く<array>
)を確認する必要があります。これは、非常に読みやすく、理解しやすいC ++標準ライブラリの一部です。
std::array
は、他のC ++コンテナのセマンティクスのような「通常の」値を与えるC配列のゼロオーバーヘッドラッパーとして設計されています。
追加機能を楽しんでいる間は、ランタイムパフォーマンスの違いに気付かないはずです。
C ++ 11またはブーストが手元にある場合は、スタイル配列のstd::array
代わりに使用int[]
することをお勧めします。
それはよりパフォーマンスが良いですか?
まったく同じである必要があります。定義上、これは配列を唯一のメンバーとして含む単純な集合体です。
std::array
特定のプラットフォームによっては、C-arrayと比較して常に同じアセンブリコードが生成されるとは限らないため、状況はより複雑に見えます。
#include <array>
void test(double* const C, const double* const A,
const double* const B, const size_t size) {
for (size_t i = 0; i < size; i++) {
//double arr[2] = {0.e0};//
std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler
for (size_t j = 0; j < size; j++) {
arr[0] += A[i] * B[j];
arr[1] += A[j] * B[i];
}
C[i] += arr[0];
C[i] += arr[1];
}
}
GCCとClangは、Cアレイバージョンとバージョンの両方で同一のアセンブリコードを生成しstd::array
ます。
ただし、MSVCとICPCは、アレイのバージョンごとに異なるアセンブリコードを生成します。(私はICPC19を-Ofast
とでテストしました-Os
; MSVC-Ox
と-Os
)
なぜそうなるのか、私にはわかりません(std :: arrayとc-arrayの動作はまったく同じだと思います)。たぶん、採用されているさまざまな最適化戦略があります。
少しおまけとして:ICPCにはバグがあるようです。
#pragma simd
状況によってはc-arrayを使用する場合のベクトル化用(c-arrayコードは間違った出力を生成します。std::array
バージョンは正常に機能します)。
残念ながら、非常に複雑なコードを最適化する際にその問題を発見したため、そのための最小限の実用的な例はまだありません。
C-array /std::array
とについて何かを誤解しただけではないと確信できる場合は、Intelにバグレポートを提出し#pragma simd
ます。