Wie durch einen bestimmten Variantentyp
using V = std::variant<bool, char, std::string, int, float, double, std::vector<int>>;
deklarieren Sie zwei Variantentypen
using V1 = std::variant<bool, char, int, float, double>;
using V2 = std::variant<std::string, std::vector<int>>;
Woher V1
gehören alle arithmetischen Typen von V
und V2
alle nicht-arithmetischen Typen von V
?
V
kann ein Parameter einer Vorlagenklasse sein, zum Beispiel:
template <class V>
struct TheAnswer
{
using V1 = ?;
using V2 = ?;
};
Im Allgemeinen können die Kriterien eine constexpr
Variable wie diese sein:
template <class T>
constexpr bool filter;
c++
c++17
std-variant
Alexey Starinsky
quelle
quelle
Types...
innenstd::variant
direkt, wie das ?std::variant
schlecht geformt.std::variant<>
schlecht geformt, also bin ich im klaren. Ich werde es so optimierenV1
und daraufV2
zurückgreifenstd::variant<std::monostate>
.Bei Boost.Mp11 ist dies (wie immer) ein kurzer Einzeiler :
Sie können auch verwenden:
um die beiden symmetrischer zu machen.
Alternative,
quelle
mp_filter
basiert das?BEARBEITEN Da eine leere Variante (
std::variant<>
) schlecht geformt ist (gemäß cppreference ) undstd::variant<std::monostate>
stattdessen verwendet werden sollte, habe ich die Antwort geändert (einetuple2variant()
Spezialisierung für leeres Tupel hinzugefügt ), um den Fall zu unterstützen, wenn die Liste der Typen fürV1
oderV2
leer ist.Es ist ein kleines
decltype()
Delirium, aber ... wenn Sie ein Hilfsfilter-Funktionspaar wie folgt deklarierenund eine Tupel-Varianten-Funktion (mit einer Spezialisierung für leere Tupel, um ein leeres zu vermeiden
std::variant
)Ihre Klasse wird einfach (?)
Wenn Sie etwas allgemeineres wünschen (wenn Sie
std::arithmetic
als Vorlagenparameter übergeben möchten ), können Sie diefilterArithm()
Funktion ändern, die einen Vorlagenparameter-Filterparameter übergibtF
(umbenanntfilterType()
).Die
TheAnswer
Klasse wirdund die
TA
Erklärung nehmen auchstd::is_arithmetic
Das Folgende ist ein vollständiges Kompilierungsbeispiel mit
std::is_arithmetic
als Parameter und einemV2
leeren Fallquelle
void
.void
, soweit ich weiß, ist als Eingabe in a verbotenstd::variant
.std::variant<void>
es schlecht geformt ist, aber es scheintstd::variant<>
in Ordnung zu sein, wenn seine Definition nicht instanziiert wird .