Betrachten Sie Folgendes: ( Wandbox )
%Vor% Gegeben sei eine Sequenz von std::array<T, length1>
, std::array<T, length2>
, ..., std::array<T, lengthK>
, wie kann ich den obigen Code verallgemeinern und eine Funktion schreiben, die die Sequenz zu einem std::array<T, sum(lengths)>
?
Es wäre schön, wenn es eine Möglichkeit gäbe, eine wiederverwendbare Funktion zu schreiben, die eine ähnliche Folge von Template-Klassen mit einer gegebenen binären Operation reduziert, zB concat
im obigen Beispiel, anstatt eine spezielle Methode zu schreiben (welche müsste jedes Mal neu geschrieben werden, wenn sich das binäre Op ändert).
(IICU, die relevanten Algorithmen der Standardbibliothek ( accumulate
, reduce
) funktionieren nur, wenn die Klasse des Ergebnisses der binären Operation immer gleich ist.)
Gegeben sei eine Sequenz von
verknüpft?std::array<T, length1>
,std::array<T, length2>
, ...,std::array<T, lengthK>
, wie kann ich eine Funktion schreiben, die die Sequenz zu einemstd::array<T, sum(lengths)>
?
Hier ist eine C ++ 17-Lösung. Es kann sehr wahrscheinlich verkürzt und verbessert werden, indem daran gearbeitet wird.
%Vor%Verwendung:
%Vor%Funktioniert sowohl mit g ++ 7 als auch mit clang ++ 5 .
Meine erste Argumentationslinie wäre, das Array in ein Tupel von Referenzen zu verwandeln (ein Bindeglied), mit tuple_cat
zu manipulieren und dann jede Operation auszuführen, die notwendig ist, um das endgültige Array zu erstellen (dh entweder verschieben oder kopieren) zu den ursprünglich übergebenen Argumenten):
erwartete Ergebnisse:
%Vor%Hier ist eine einfache C ++ 17-Lösung über Falte Ausdrücke :
%Vor%Beispiel für die Verwendung:
%Vor%Streng C ++ 11; nicht so lesbar wie @ Jarod42, aber möglicherweise viel effizienter mit vielen Arrays, wenn der Aufrufbaum nicht vollständig abgeflacht ist (in Bezug auf Inlining), da nur ein Ergebnisobjekt vorhanden ist und nicht mehrere temporäre, progressiv wachsende Ergebnisobjekte:
%Vor% Beachten Sie, dass dies auch ordnungsgemäß weitergeleitet wird, indem Sie den Algorithmus std::move
für rvalues und nicht für% co_de verwenden %.
Dies wird nicht verallgemeinert, sondern nutzt die Tatsache aus, dass wir, wenn wir zwei Arrays innerhalb einer Reihe von Klammern splattern, diese verwenden können, um ein neues Array zu initialisieren.
Ich bin mir nicht sicher, wie nützlich Generalisierung ist, in jedem Fall. Angesichts einer Reihe von Feldern mit nicht übereinstimmenden Größen, was gibt es sonst noch zu tun, aber verbinden Sie sie alle zusammen?
%Vor%