Cómo por un tipo de variante dado
using V = std::variant<bool, char, std::string, int, float, double, std::vector<int>>;
declarar dos tipos de variantes
using V1 = std::variant<bool, char, int, float, double>;
using V2 = std::variant<std::string, std::vector<int>>;
donde V1
incluye todos los tipos aritméticos de V
e V2
incluye todos los tipos no aritméticos de V
?
V
puede ser un parámetro de una clase de plantilla, por ejemplo:
template <class V>
struct TheAnswer
{
using V1 = ?;
using V2 = ?;
};
en general los criterios pueden ser una constexpr
variable como esta:
template <class T>
constexpr bool filter;
c++
c++17
std-variant
Alexey Starinsky
fuente
fuente
Types...
el interiorstd::variant
directamente, como esta ?std::variant
está mal formado.std::variant<>
está mal formada, así que estoy claro. Voy a ajustar de modo queV1
yV2
caer de nuevo astd::variant<std::monostate>
pesar.Con Boost.Mp11 , este es un breve resumen (como siempre):
También puedes usar:
para hacer los dos más simétricos.
Alternativamente,
fuente
mp_filter
basa esto ?EDITAR Dado que una variante vacía (
std::variant<>
) está mal formada (según cppreference ) y que debería usarse en sustd::variant<std::monostate>
lugar, he modificado la respuesta (agregué unatuple2variant()
especialización para tuplas vacías) para admitir el caso cuando la lista de tipos paraV1
oV2
está vacía.Es un pequeño
decltype()
delirio pero ... si declaras un par de funciones de filtro auxiliar de la siguiente maneray una función tupla a variante (con una especialización para tuplas vacías, para evitar un vacío
std::variant
)tu clase simplemente (?) se convierte
Si desea algo más genérico (si desea pasar
std::arithmetic
como parámetro de plantilla), puede modificar lafilterArithm()
función pasando un parámetro de filtro de plantilla-plantillaF
(renombradofilterType()
)La
TheAnswer
clase se conviertey la
TA
declaración toma tambiénstd::is_arithmetic
El siguiente es un ejemplo completo de compilación con un
std::is_arithmetic
parámetro y unV2
caso vacíofuente
void
.void
, que yo sepa, está prohibido como tipo en astd::variant
.std::variant<void>
está mal formado, pero parece questd::variant<>
está bien si su definición no se instancia .