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)을 쓰려면 TCopyConstructible 요구사항을, (2)를 쓰려면 MoveConstructible 요구사항을 만족해야 해요.

  • 반환 값:

    • (1) {{a[0], ..., a[N - 1]}}
    • (2) {{std::move(a[0]), ..., std::move(a[N - 1])}}

클래스 템플릿 인자 추론(CTAD)으로는 std::array의 길이를 자동으로 추론할 수 없는 상황이 있어요. 그런 경우 to_array가 유용해요.

  • to_arraystd::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로 옮길 수 있어요.

더 알아보기 (Learn more)

cppreference