Namespaces
Variants

std:: to_array

From cppreference.net
Definiert im Header <array>
template < class T, std:: size_t N >
constexpr std:: array < std:: remove_cv_t < T > , N > to_array ( T ( & a ) [ N ] ) ;
(1) (seit C++20)
template < class T, std:: size_t N >
constexpr std:: array < std:: remove_cv_t < T > , N > to_array ( T ( && a ) [ N ] ) ;
(2) (seit C++20)

Erstellt ein std::array aus dem eindimensionalen eingebauten Array a . Das Kopieren oder Verschieben mehrdimensionaler eingebauter Arrays wird nicht unterstützt.

1) Für jedes i in 0, ..., N - 1 , kopierinitialisiert das entsprechende Element des Ergebnisses mit a [ i ] . Diese Überladung ist fehlerhaft, wenn std:: is_constructible_v < T, T & > false ist.
2) Für jedes i in 0, ..., N - 1 , bewegt-initialisiert das entsprechende Element des Ergebnisses mit std :: move ( a [ i ] ) . Diese Überladung ist fehlerhaft, wenn std:: is_move_constructible_v < T > false ist.

Beide Überladungen sind fehlerhaft, wenn std:: is_array_v < T > true ist.

Inhaltsverzeichnis

Parameter

a - das einzubauende Array, das in std::array umgewandelt werden soll
Typanforderungen
-
T muss die Anforderungen von CopyConstructible erfüllen, um Überladung (1) zu verwenden.
-
T muss die Anforderungen von MoveConstructible erfüllen, um Überladung (2) zu verwenden.

Rückgabewert

1) std:: array < std:: remove_cv_t < T > , N > { a [ 0 ] , ..., a [ N - 1 ] }
2) std:: array < std:: remove_cv_t < T > , N > { std :: move ( a [ 0 ] ) , ..., std :: move ( a [ N - 1 ] ) }

Hinweise

Es gibt einige Gelegenheiten, bei denen Class Template Argument Deduction von std::array nicht verwendet werden kann, während to_array verfügbar ist:

  • to_array kann verwendet werden, wenn der Elementtyp des std::array manuell angegeben wird und die Länge abgeleitet wird, was vorzuziehen ist, wenn implizite Konvertierung gewünscht wird.
  • to_array kann ein String-Literal kopieren, während die Klassentemplate-Argumentableitung ein std::array eines einzelnen Zeigers auf sein erstes Zeichen konstruiert.
std::to_array<long>({3, 4}); // OK: implizite Konvertierung
// std::array<long>{3, 4};   // Fehler: zu wenige Template-Argumente
std::to_array("foo");        // erzeugt std::array<char, 4>{'f', 'o', 'o', '\0'}
std::array{"foo"};           // erzeugt std::array<const char*, 1>{"foo"}
Feature-Test Makro Wert Std Feature
__cpp_lib_to_array 201907L (C++20) std::to_array

Mögliche Implementierung

to_array (1)
namespace detail
{
    template<class T, std::size_t N, std::size_t... I>
    constexpr std::array<std::remove_cv_t<T>, N>
        to_array_impl(T (&a)[N], std::index_sequence<I...>)
    {
        return {{a[I]...}};
    }
}
template<class T, std::size_t N>
constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&a)[N])
{
    return detail::to_array_impl(a, std::make_index_sequence<N>{});
}
to_array (2)
namespace detail
{
    template<class T, std::size_t N, std::size_t... I>
    constexpr std::array<std::remove_cv_t<T>, N>
        to_array_impl(T (&&a)[N], std::index_sequence<I...>)
    {
        return {{std::move(a[I])...}};
    }
}
template<class T, std::size_t N>
constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&&a)[N])
{
    return detail::to_array_impl(std::move(a), std::make_index_sequence<N>{});
}
**Anmerkung:** Da der Text innerhalb der `
`-Tags C++-Code enthält und gemäß den Anweisungen nicht übersetzt werden soll, sowie alle HTML-Tags und Attribute unverändert bleiben müssen, wurde nur der beschreibende Text außerhalb der Codeblöcke übersetzt. In diesem Fall gab es keinen zu übersetzenden Text außerhalb der Codeblöcke, daher bleibt die Ausgabe identisch mit der Eingabe.

Beispiel

#include <array>
#include <memory>
#include <string_view>
#include <type_traits>
#include <utility>
// erstellt ein constexpr Array von string_view's    
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()
{
    // kopiert ein String-Literal
    auto a1 = std::to_array("foo");
    static_assert(a1.size() == 4);
    // leitet sowohl Elementtyp als auch Länge ab
    auto a2 = std::to_array({0, 2, 1, 3});
    static_assert(std::is_same_v<decltype(a2), std::array<int, 4>>);
    // leitet Länge mit spezifiziertem Elementtyp ab
    // implizite Konvertierung findet statt
    auto a3 = std::to_array<long>({0, 1, 3});
    static_assert(std::is_same_v<decltype(a3), std::array<long, 3>>);
    auto a4 = std::to_array<std::pair<int, float>>(
        {{3, 0.0f}, {4, 0.1f}, {4, 0.1e23f}});
    static_assert(a4.size() == 3);
    // erstellt ein nicht-kopierbares std::array
    auto a5 = std::to_array({std::make_unique<int>(3)});
    static_assert(a5.size() == 1);
    // Fehler: Kopieren mehrdimensionaler Arrays wird nicht unterstützt
    // char s[2][6] = {"nice", "thing"};
    // auto a6 = std::to_array(s);
}

Siehe auch

(library fundamentals TS v2)
erstellt ein std::array Objekt, dessen Größe und optionaler Elementtyp von den Argumenten abgeleitet werden
(Funktions-Template)