Ho dichiarato un boost::variant
che accetta tre tipi: string
, bool
e int
. Il seguente codice mostra che la mia variante accetta const char*
e la converte in bool
. È normale che boost::variant
accetti e converta tipi non presenti nel suo elenco?boost :: variant - perché "const char *" è stato convertito in "bool"?
#include <iostream>
#include "boost/variant/variant.hpp"
#include "boost/variant/apply_visitor.hpp"
using namespace std;
using namespace boost;
typedef variant<string, bool, int> MyVariant;
class TestVariant
: public boost::static_visitor<>
{
public:
void operator()(string &v) const
{
cout << "type: string -> " << v << endl;
}
template<typename U>
void operator()(U &v)const
{
cout << "type: other -> " << v << endl;
}
};
int main(int argc, char **argv)
{
MyVariant s1 = "some string";
apply_visitor(TestVariant(), s1);
MyVariant s2 = string("some string");
apply_visitor(TestVariant(), s2);
return 0;
}
uscita:
Tipo: altro -> 1
Tipo: stringa -> qualche stringa
Se rimuovo il tipo bool da MyVariant e modificarla in questo modo:
typedef variant<string, int> MyVariant;
const char*
non è più convertito in bool
. Questa volta è convertito in string
e questa è la nuova uscita:
Tipo: stringa -> qualche stringa
Tipo: stringa -> qualche stringa
Ciò indica che variant
tenta di convertire altri tipi prima a bool
e quindi a string
. Se la conversione del tipo è qualcosa di inevitabile e dovrebbe sempre accadere, c'è un modo per dare una conversione a string
una priorità più alta?
Per completare la tua spiegazione: c'è una conversione implicita da qualsiasi tipo di puntatore a 'bool', e le conversioni implicite incorporate sono sempre scelte in preferenza alle conversioni definite dall'utente. (La conversione 'char *' in 'std :: string' conta come definita dall'utente.) Come per cambiare i costruttori, puoi racchiudere la classe in un'altra classe, o derivare da essa. A seconda del contesto, uno di questi può o non può essere appropriato; entrambi hanno alcuni inconvenienti. –
Penso che una soluzione sia rimuovere 'bool' da' MyVariant' e utilizzare invece i valori 0 e 1. – Meysam
@Meysam: sì. Ho pensato di raccomandarlo, ma poi ho pensato che probabilmente volevi un 'MyVariant' inizializzato con' 0' per essere diverso da un 'MyVariant' inizializzato con' false'. Se è giusto che siano uguali, basta rimuovere 'bool'. Se hanno significati diversi, non è così semplice. –