Erstens, ein Kontext: Ich benutze ein leeres struct
namens nothing
, um etwas ähnlich zu "normal void
zu emulieren. " , um einige Interfaces zu verschönern, die darauf basieren, mehrere Funktionsobjekte aneinander zu ketten.
Beispielverwendung:
%Vor% Im obigen Beispiel ist das, was passiert, dass ich alle Ergebnisse der Funktionsobjekte verpacke, die an when_all
in einem std::tuple
übergeben werden, wobei void
in nothing
konvertiert wird (in diesem Beispiel) : std::tuple<int, nothing, char>
), dann verwende ich eine Hilfsfunktion namens apply_ignoring_nothing
, die ein Funktionsobjekt aufruft, indem ich ein std::tuple
entpacke und dabei die Elemente nothing
ignoriere.
apply_ignoring_nothing
wird in call_ignoring_nothing
implementiert.
Ich habe eine Funktion call_ignoring_nothing
mit folgender Signatur:
Diese Funktion ruft f
auf, indem sie alle xs...
perfekt weiterleitet, für die die Kompilierzeit is_nothing_v<T>
false
zurückgibt.
is_nothing_v
ist wie folgt definiert:
Die Art, wie ich call_ignoring_nothing
implementiert habe, ist rekursiv . Der Basisfall benötigt nur f
und ruft ihn einfach auf:
Der rekursive Fall nimmt f
, x
und xs...
und bindet x
bedingt als eines der Argumente von f
wenn !is_nothing_v<decltype(f)>
durch ein Lambda. Es rekursiert dann über call_ignoring_nothing
und übergibt das neu erstellte Lambda als f
:
Ich möchte call_ignoring_nothing
auf iterative Weise implementieren, wobei ich möglicherweise pack expand verwende, um die Argumente ohne Rekursion herauszufiltern.
Ist es möglich, call_ignoring_nothing
ohne Rekursion zu implementieren? Ich konnte mir keine Technik vorstellen, die es erlaubt, Argumente während der Erweiterung des Pakets herauszufiltern.
Nicht so anders als beim Griwes-Vorschlag, aber ... Sie können std::apply()
, std::tuple_cat()
, std::get()
und Tupel verwenden, die leer sind oder einen Wert haben, der dem Wert von is_nothing_v
entspricht.
Ich meine ... etwas wie [Bearbeiten: verbessert mit einem Vorschlag von T.C. und ein Beispiel aus dem OP selbst (Vittorio Romeo)]
%Vor%Folgendes ist ein funktionierendes Beispiel
%Vor% Hier ist ein weiterer Take, der nicht von tuple_cat
abhängt. Berechnen Sie zunächst die Positionen, an denen eine Packung Boole true
ist, über eine "normale" constexpr-Funktionsvorlage:
Dann wandle das Ergebnis in ein index_sequence
:
Dann ist es eine einfache Sache von forward_as_tuple
+ get
mit index_sequence
:
Tags und Links c++ templates template-meta-programming c++17 metaprogramming