std::to_array
std::to_array (배열을 std::array로 변환)
1차원 내장 배열(built-in array)에서 std::array를 만들어 주는 함수예요. 함수 인자에서 배열의 길이를 자동으로 추론해 주고, 복사 또는 이동 초기화를 지원해요. C++20부터 있어요.
출처: cppreference
본문
<array> 헤더에 정의돼 있고, 1차원 내장 배열 a로부터 std::array를 만들어요. 다차원 내장 배열의 복사나 이동은 지원하지 않아요.
template< class T, std::size_t N >
constexpr std::array<std::remove_cv_t<T>, N> to_array( T (&a)[N] ); // (1)
template< class T, std::size_t N >
constexpr std::array<std::remove_cv_t<T>, N> to_array( T (&&a)[N] ); // (2)
- (1)
0, ..., N-1의 각i에 대해 결과의 해당 원소를a[i]로 복사 초기화해요.std::is_constructible_v<T, T&>가false면 ill-formed예요. - (2)
0, ..., N-1의 각i에 대해 결과의 해당 원소를std::move(a[i])로 이동 초기화해요.std::is_move_constructible_v<T>가false면 ill-formed예요.
두 오버로드 모두 std::is_array_v<T>가 true면 ill-formed예요.
-
매개변수
a:std::array로 변환할 내장 배열이에요. -
(1)을 쓰려면
T가CopyConstructible요구사항을, (2)를 쓰려면MoveConstructible요구사항을 만족해야 해요. -
반환 값:
- (1)
{{a[0], ..., a[N - 1]}} - (2)
{{std::move(a[0]), ..., std::move(a[N - 1])}}
- (1)
클래스 템플릿 인자 추론(CTAD)으로는 std::array의 길이를 자동으로 추론할 수 없는 상황이 있어요. 그런 경우 to_array가 유용해요.
to_array는std::array의 원소 타입을 수동으로 지정하고 길이만 추론할 때 쓸 수 있어요. 암시적 변환이 필요할 때 선호돼요.to_array는 문자열 리터럴을 복사할 수 있는데, CTAD는 첫 문자를 가리키는 단일 포인터의std::array를 만들어요.
std::to_array<long>({3, 4}); // OK: 암시적 변환
// std::array<long>{3, 4}; // error: 템플릿 인자가 너무 적음
std::to_array("foo"); // std::array<char, 4>{'f', 'o', 'o', '\0'} 생성
std::array{"foo"}; // std::array<const char*, 1>{"foo"} 생성
피처 테스트 매크로 __cpp_lib_to_array는 값 201907L로 C++20에서 std::to_array를 나타내요.
예제를 보면요.
#include <array>
#include <memory>
#include <string_view>
#include <type_traits>
#include <utility>
// string_view들의 constexpr 배열 생성
constexpr auto w1n = std::to_array<std::string_view>({
"Mary", "Patricia", "Linda", "Barbara", "Elizabeth", "Jennifer"
});
static_assert(std::is_same_v<decltype(w1n), const std::array<std::string_view, 6>>);
static_assert(w1n.size() == 6 and w1n[5] == "Jennifer");
int main()
{
// 문자열 리터럴 복사
auto a1 = std::to_array("foo");
static_assert(a1.size() == 4);
// 원소 타입과 길이 둘 다 추론
auto a2 = std::to_array({0, 2, 1, 3});
static_assert(std::is_same_v<decltype(a2), std::array<int, 4>>);
// 복사 불가한 std::array 생성
auto a5 = std::to_array({std::make_unique<int>(3)});
static_assert(a5.size() == 1);
// error: 다차원 배열 복사는 지원 안 함
// char s[2][6] = {"nice", "thing"};
// auto a6 = std::to_array(s);
}
이렇게 원소 타입과 길이를 함께 추론하거나, 복사할 수 없는 타입도 std::array로 옮길 수 있어요.