Iterativ Filtern von Argumenten, die bei der Kompilierung mit einem Vergleichselement übereinstimmen

8

Kontext

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.

%Vor%

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.

%Vor%

apply_ignoring_nothing wird in call_ignoring_nothing implementiert.

Frage

Ich habe eine Funktion call_ignoring_nothing mit folgender Signatur:

%Vor%

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:

%Vor%

Die Art, wie ich call_ignoring_nothing implementiert habe, ist rekursiv . Der Basisfall benötigt nur f und ruft ihn einfach auf:

%Vor%

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 :

%Vor%

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.

    
Vittorio Romeo 17.09.2017, 17:18
quelle

2 Antworten

6

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%

Live-Beispiel in der Wandbox

    
max66 17.09.2017, 19:48
quelle
1

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:

%Vor%

Dann wandle das Ergebnis in ein index_sequence :

um %Vor%

Dann ist es eine einfache Sache von forward_as_tuple + get mit index_sequence :

%Vor%     
T.C. 19.09.2017 17:20
quelle