Designfrage: Tail einer leeren Liste
-
Hallöle,
Ich bastle mir gerade eine TMP-Lib. Für Listen, repräsentiert durch das list-Template gibt es eine Template-Metafunktion "tail". Sollte tail bei einer leeren Liste ebenfalls eine leere Liste zurückgeben, oder sollte da eine static_assertion fliegen?
Grüße,
Der Kellerautomat
-
static assertion.
Leere Listen sind ein gängiges Abbruchkriterium für die Rekursion. Wer das missachtet, hat wahrscheinlich einen Fehler gemacht.
-
Hm, okay. Ist es eigentlich besser, wenn der User die Fehlermeldung vom Compiler + die Assertion bekommt, oder wenn ich dafür sorge, dass das Template im Fehlerfall gar nicht instanziert wird und der User somit nur die Assertion bekommt?
Sprich:
namespace detail { template <typename L> struct tail : tail<typename L::type> {}; template <typename Head, typename... Tail> struct tail<list<Head, Tail...>> : list<Tail...> {}; } template <typename L> struct tail : extend_if // prevent messy template error from propagating for empty lists < length<L>, detail::tail<L> > { static_assert(length<L>::value != 0, "tail of empty list requested"); };
Man beachte den Kommentar. extend_if ist, wenn die Bedingung (hier Länge ungleich 0) wahr ist, von typename detail::tail<L>::type abgeleitet, andernfalls leer. Somit bekäme der User im Fehlerfall nur den Fehler der Assertion, weil detail::tail nicht instanziert wird.
-
Auch wenn es vielleicht eleganter erscheint das Instanziieren sofort zu verhindern, ich glaube jeder User wird dir dankbar sein für eine ordentlich Lesbare Fehlermeldung anstatt des Template-Stacks, den eine TMP-Liste so hinter sich herzieht.