كيفية تنفيذ نموذج البديل الأساسي (والزائر على البديل) في C ++؟
سؤال
لقد حاولت القراءة:
http://www.boost.org/doc/libs/1_41_0/boost/variant.hpp
http://www.codeproject.com/KB/cpp/TTLTyplist.aspx
and chapter 3 of "Modern C++ Design"
لكن لا يزال لا يفهم كيف يتم تنفيذ المتغيرات. هل يمكن لأي شخص لصق مثال قصير على كيفية تحديد شيء مثل:
class Foo {
void process(Type1) { ... };
void process(Type2) { ... };
};
Variant<Type1, Type2> v;
v.somethingToSetupType1 ...;
somethingToTrigger process(Type1);
v.somethingToSetupType2 ...;
somethingToTrigger process(Type2);
شكرًا!
المحلول
إذا اضطررت إلى تحديد كائن متغير ، فربما أبدأ بما يلي:
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);
}
ثم استخدام ناقلات MPL لجعل النهج يعمل لأكثر من نوعين مختلفين فقط.
في النهاية ، يمكنك كتابة شيء مثل هذا:
Variant<Type1, Type2> v;
class MyVisitor
{
public:
operator()(Type1);
operator()(Type2);
};
MyVisitor visitor;
v = Type1();
visit(visitor, v);
v = Type2();
visit(visitor, v);
NB: لا توجد فرصة لتجميع هذا الرمز ، ولكن هذا يصف الأفكار التي أستخدمها.
نصائح أخرى
أنا فكر في أنت تسأل كيف استعمال المتغيرات ، وليس كيف ينفذ معهم. قد ترغب في إلقاء نظرة على زيادة الوثائق على المتغيرات; ؛ سيكون هذا أكثر فائدة من النظر إلى ملف الرأس.
ثم قد يبدو مثالك مثل هذا:
class v_visitor : public boost::static_visitor
{
public:
void operator()(Type1 &t) const {...}
void operator()(Type2 &t) const {...}
};
v = Type1(...);
boost::apply_visitor(v_visitor(), v);
لا تنتمي إلى StackOverflow