Die Lösung, die durch @ Richard Hodges erfordert die Klasse, die mit char Array initialisiert werden, wie zum char const*
gegenüber, die ändert die Signatur des Konstruktors. Wenn das nicht für Ihren Fall nicht funktioniert, dann ist hier eine Lösung, die funktioniert nicht Änderung der Unterschrift:
template<int N>
class A
{
template<size_t...Is>
A(const char * s, std::index_sequence<Is...>)
: _assert(std::strlen(s) <= N, "size of buffer is bigger than N"),
buf{ (Is, *s != '\0'? *s++: *s)... }
{}
public:
A(const char *s) : A(s, std::make_index_sequence<N>()) {}
private:
throwable _assert;
const char buf[N];
};
wo throwable
ist wie folgt definiert:
struct throwable
{
throwable(bool b, char const * message){
if (not b)
throw std::invalid_argument(message);
}
};
Die Verwendung von throwable
stellt sicher, dass buf
wird nicht mit Puffer größer als N
Bytes initialisiert. Wenn Ihre Situation jedoch sicherstellt, dass diese Überprüfung nicht erforderlich ist, können Sie sie entfernen. Der Code sollte auch ohne ihn funktionieren, aber ich würde vorschlagen, dass Sie ihn mindestens in debug Modus halten.
beachte, dass die Zugabe von _assert
als Mitglied der Größe der Klasse, um ein Byte mindestens erhöht. Um dies zu vermeiden, könnten wir empty base class optimiation verwenden und tun dies statt:
template<int N>
class A : private throwable
{
template<size_t...Is>
A(const char * s, std::index_sequence<Is...>)
: throwable(std::strlen(s) <= N, "size of buffer is bigger than N"),
buf{ (Is, *s != '\0'? *s++: *s)... }
{}
public:
A(const char *s) : A(s, std::make_index_sequence<N>()) {}
private:
const char buf[N];
};
Das spart uns 1 Byte pro Instanz.
Können Sie 'char buf [N]' auf 'std :: ändern array'? – Jarod42
@ Jarod42 Nein, leider. Ich habe keinen Zugang zu STL. – Ana
@Ana können Sie die Quellen von 'libstdC++' oder etwas kopieren? Selbst wenn Sie keinen Zugriff auf 'std :: array' haben, werden Sie es jetzt neu implementieren. Wahrscheinlich schlechter als in der ursprünglichen Implementierung. –