2015-11-02 4 views
5

Ich habe eine Dateistruktur, wo feste Länge Strings keinen Nullhinter hat initialisieren. Wie Felder wie std :: Array initialisieren, ohne Nullhinter:Wie ein std :: Array <char, N> mit einem Stringliteral Weglassen der hinteren ‚ 0‘

#pragma pack(push, 1) 
struct Data { 
    // Compiles, but it has an undesired '\0': 
    std::array<char, 6> undesired_number{"12345"}; 
    // Does not compile: 
    std::array<char, 5> number{"12345"}; // stripping '\0' 
}; 
#pragma pack(pop) 
+0

Was ist der Compiler-Fehler? Inkompatible Typen? Ich fürchte, es ist einfach nicht möglich, basierend auf einem Zeichenkettenliteral. –

+3

Warum müssen Sie ein String-Literal verwenden, um es zu initialisieren? – Barmar

+0

@Barmar nur für die Bequemlichkeit –

Antwort

11

machen eine Hilfsfunktion

template <std::size_t N, std::size_t ... Is> 
std::array<char, N - 1> to_array(const char (&a)[N], std::index_sequence<Is...>) 
{ 
    return {{a[Is]...}}; 
} 

template <std::size_t N> 
std::array<char, N - 1> to_array(const char (&a)[N]) 
{ 
    return to_array(a, std::make_index_sequence<N - 1>()); 
} 

Und dann

struct Data { 
    std::array<char, 5> number{to_array("12345")}; // stripping '\0' 
}; 

Demo

+0

Ich frage mich, ob dies in eine Kopie des Literals kompilieren wird, oder zwei, eins mit Terminator und eins ohne. – luk32

+0

@ luk32, hängt von den Compiler- und Optimierungseinstellungen ab. Zum Beispiel hat g ++ mit O3 überhaupt kein Literal. – SergeyA

+0

funktioniert gut mit C++ 11 nach einem 'make_index_sequence' Beschaffen und Wechsel zu' std :: array number = to_array ("12345"); ' –

0

Ein Zeichenfolgenliteral ist NUL-terminiert, in C++ (im Gegensatz zu C) Sie kann es nicht durch die Bereitstellung einer Length - 1 Größe aus; Daher kann es nicht direkt, auch getan werden, man bedenkt, dass array intern ein T[N] ist.

+0

Der Standard nicht, dass 'erfordert ein' T [N] 'array' intern sein. Einige denken, es sollte, für die Fälle 'N> 0 'sowieso –

Verwandte Themen