C
atze123 schrieb:
Ok, aber mit std::array<> und std::tuple_size<>::size erzielt es den gleichen Effekt. Obwohl konstante Compile Time Expression. Oder was genau versteh ich da falsch?
Ja. Ich habe auf zwei Probleme hingewiesen, konstante Ausdrücke sind ist nur eines davon.
Entscheidend ist zunächst einmal, dass Instantiierung von Templates und Auswertung von Ausdrücken nichts miteinander zu tun hat.
Es spielt schlicht keine Rolle, welchen Wert eine Bedingung bei if, oder eines bedingten Ausdruckes hat - selbst wenn dieser bereits während des Compilierens bekannt ist - hinsichtlich der Instantiierung der Zweige der Bedingung. In
if (true) foo(); else bar();
wiseen wir, dass der else-Zweig nie betreten wird, syntaktisch korrekt muss er trotzdem sein, und Templates werden dafür ggf. instantiiert. Beim conditional-if kommt hinzu, dass wir den Typ des gesamten Ausdrucks nur kennen, wenn der Typ beider Zweige bekannt ist; das erfordert nat. ebenso eine Instantiierung. Gerade deshalb gehören Templatespezialisierungen zum Grundwerkzeug der Templateprogrammierung, weil Rekursionen anders nicht abzuschliessen sind.
Im Zusammenhang mit Paramterpacks ist es häufig so, dass diese indiziert werden können; das Problem eine Reihe von n Werten oder Typen zu erzeugen, kann dann einfach auf das Problem, eine Sequenz 0,1,...,n-1 zu erzeugen, zurückgeführt werden. Weil das so ist, gibt es ab C++14 auch in der Standardbibliothek Mittel hierfür.
template <typename Function, typename Container, std::size_t... I>
constexpr auto apply(Function&& f, Container&& c, std::index_sequence<I...>) {
return std::forward<Function>(f)(std::forward<Container>(c)[I]...);
}
template <typename Function, typename T, std::size_t N>
constexpr auto apply(Function&& f, T(&a)[N]) {
return apply(std::forward<Function>(f), a, std::make_index_sequence<N>{});
}