다음과 같은 매우 간단한 배열을 만들고 싶다면
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>
동일한 초기화 목록으로 변경하면 갑자기 "너무 많은 초기화 프로그램"오류가 발생합니다. (VS 2019 Community with language = C ++ 17)
std::array
초기화 에서 이중 대괄호가 사용되는 이유는 무엇 입니까?
답변:
A std::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 배열에 대한 제로 오버 헤드 래퍼로 설계되었습니다.
추가 기능을 계속 즐길 수있는 동안에는 런타임 성능의 차이를 느끼지 않아야합니다.
스타일 배열 std::array
대신 사용 하는 것은 int[]
C ++ 11 또는 부스트가 있다면 좋은 생각입니다.
더 성능이 좋습니까?
정확히 동일해야합니다. 정의에 따라 배열을 유일한 구성원으로 포함하는 단순 집계입니다.
std::array
특정 플랫폼에 따라 항상 C-array와 동일한 어셈블리 코드를 생성하는 것은 아니기 때문에 상황은 더 복잡해 보입니다 .
나는 godbolt 에서이 특정 상황을 테스트했습니다 .
#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-array 버전과 버전 모두에 대해 동일한 어셈블리 코드를 생성합니다 std::array
.
그러나 MSVC 및 ICPC 는 각 어레이 버전에 대해 서로 다른 어셈블리 코드를 생성합니다. (나는 ICPC19를 -Ofast
and -Os
; MSVC -Ox
및 -Os
)
왜 이것이 사실인지 모르겠습니다 (실제로 std :: array 및 c-array의 정확히 동일한 동작을 기대합니다). 다른 최적화 전략이 사용되었을 수 있습니다.
약간의 추가 사항 : ICPC에 버그가있는 것 같습니다.
#pragma simd
일부 상황에서 c-array를 사용할 때 벡터화를 위해 (c-array 코드가 잘못된 출력을 생성하고 std::array
버전이 잘 작동 함).
불행히도, 꽤 복잡한 코드를 최적화하는 동안 그 문제를 발견했기 때문에 아직 최소한의 작업 예제가 없습니다.
C-array / std::array
및에 대해 오해하지 않았다고 확신하는 경우 인텔에 버그 보고서를 제출할 것 #pragma simd
입니다.