Si je devais définir un objet variant, je serais probablement commencer par ce qui suit:
template<typename Type1, typename Type2>
class VariantVisitor;
template<typename Type1, typename Type2>
class Variant
{
public:
friend class VariantVisitor<Type1, Type2>;
Variant();
Variant(Type1);
Variant(Type2);
// + appropriate operators =
~Variant(); // deal with memory management
private:
int type; // 0 for invalid data, 1 for Type1, 2 for Type2
void* data;
};
template<typename Visitor, typename Type1, typename Type2>
class VariantVisitor
{
private:
Visitor _customVisitor;
public:
void doVisit(Variant<Type1, Type2>& v)
{
if(v.type == 1)
{
_customVisitor(*(Type1*)(v.data));
}
else if(v.type == 2)
{
_customVisitor(*(Type2*)(v.data));
}
else
{
// deal with empty variant
}
}
};
template<typename Visitor, typename Type1, typename Type2>
void visit(Visitor visitor, Variant<Type1, Type2> v)
{
VariantVisitor<Visitor, Type1, Type2>(visitor).doVisit(v);
}
puis utilisez MPL vectors pour faire le travail d'approche pour plus que deux types différents.
En fin de compte, vous pourriez écrire quelque chose comme ceci:
Variant<Type1, Type2> v;
class MyVisitor
{
public:
operator()(Type1);
operator()(Type2);
};
MyVisitor visitor;
v = Type1();
visit(visitor, v);
v = Type2();
visit(visitor, v);
NB: il n'y a aucune chance de ce code compile, mais cela décrit les idées j'utiliser.
Demandez-vous comment implémenter des variantes, ou comment utiliser la mise en œuvre de coup de pouce? – Anne
Il est clair qu'il veut savoir comment implémenter des variantes. –
Je veux savoir comment _implement_; pas comment utiliser _use_ variantes. – anon