c++ - check boost:: variant<T> para null
(5)
Boost.Variant tiene una garantía nunca vacía , lo que significa que siempre debe almacenar algo de valor. Se garantiza que el miembro empty
siempre devuelve false
y existe solo por compatibilidad.
Tengo una variante :: boost en mi programa y quiero verificar si la variante en sí está inicializada y también si hay un valor contenido en uno de sus tipos.
He intentado vacío () en la variante, pero eso no parece funcionar. Tampoco verificando contra NULL.
¿Alguien sabe cómo comprobar esto?
EDIT: Ok, parece que nunca estará vacío, pero no siempre habrá un valor en sus tipos contenidos, entonces, ¿cómo verifico una situación sin valor?
Si ve mi pregunta con respecto a la garantía de nunca vaciar y el almacenamiento único , boost::variant
admite un tipo de valor similar a NIL llamado boost::blank
. lo que garantizará que la variante nunca use el montón como almacenamiento de respaldo
Puede detectar qué tipo se almacena utilizando boost::variant<>::which()
que devuelve un índice entero del tipo de variante enlazada; así que si usa en blanco como primer tipo, el cual () devolverá 0 cuando esté en blanco
ver el siguiente ejemplo
typedef boost::variant< boost::blank , int , std::string > var_t;
var_t a;
assert( a.which() == 0 );
a = 18;
assert( a.which() == 1 );
espero que esto ayude
También puede usar boost::variant<boost::blank, int, double, long double> number;
Y la variante de función empty()
. Devuelve falso si la variante siempre contiene exactamente uno de sus tipos acotados. (Consulte la sección llamada Garantía de nunca vaciar para obtener más información).
Un método para asegurarse de que tiene una variante bien definida es incluir un "NullType" en su lista de variantes. Si bien puede ser necesario escribir más código en los "visitantes" que escribirá para usarlo, pueden hacer excepciones para que los operadores sepan que algo está mal. Generalmente estoy en contra de tales controles de tiempo de ejecución, pero a veces, realmente no hay otra manera. Basta con decir que:
class NullType{};
Luego agréguelo como el primer argumento a la lista de variantes. Como han dicho otros y la documentación de impulso describe que nunca tendrá una situación donde una variante está vacía. Sin embargo, puede hacer una verificación de tipo para asegurarse de que nunca podrá compilar con "NullType" si no sobrecarga las funciones o si se lanza una excepción de tiempo de ejecución si tiene un "NullType".
Ahora su variante:
boost::variant<NullType, int, double, long double> number;
class DoSomething : boost:static_visitor<void>{
public:
void visit(const int& _item);
void visit(const double& _item);
void visit(const long double& _item);
void visit(const NullType& _uhOh);
};
Una boost::variant
se inicializa siempre.
Si no lo inicializó explícitamente, el primer elemento se construyó utilizando su constructor predeterminado:
struct Foo {};
struct Bar {};
struct Visitor: boost::static_visitor<>
{
void operator()(Foo const& foo) const { std::cout << "Foo/n"; }
void operator()(Bar const& bar) const { std::cout << "Bar/n"; }
};
int main(int argc, char* argv[])
{
boost::variant<Foo,Bar> var;
boost::apply_visitor(Visitor(), var); // prints Foo
return 0;
}