2012-06-20 12 views
6

यदि मेरे boost::variant में सभी प्रकार एक ही विधि का समर्थन करते हैं, तो क्या इसे सामान्य रूप से कॉल करने का कोई तरीका है (यानी static_visitor की प्रत्येक विधि के लिए इसे अलग से कॉल नहीं करना)?बूस्ट में टाइप करने के लिए सामान्य कॉलिंग विधियां :: संस्करण

मैं काम करने के लिए कुछ इस तरह प्राप्त करने के लिए कोशिश कर रहा हूँ:

class A 
{ 
    void boo() {} 
}; 

class B 
{ 
    void boo() {} 
}; 

class C 
{ 
    void boo() {} 
}; 

typedef boost::variant<A, B, C> X; 

void foo(X& d) 
{ 
    x.boo(); 
} 

लेकिन यह 'boo' : is not a member of 'boost::variant<T0_,T1,T2>' कह संकलित करने के लिए विफल रहता है।

वर्तमान में, मेरे पास कुछ कक्षाएं हैं जो सभी इंटरफ़ेस से प्राप्त होती हैं ताकि उनकी एकल साझा विधि को पॉलिमॉर्फिक रूप से उपयोग किया जा सके। मैं भी आगंतुक के माध्यम से कक्षाओं का उपयोग करने में सक्षम होना चाहता हूं क्योंकि सभी अन्य विधियां प्रत्येक ठोस वर्ग के लिए अद्वितीय हैं। मैं उम्मीद कर रहा था कि boost::variant यहां अपने स्वयं के आगंतुक तंत्र को लागू करने का बेहतर विकल्प हो सकता है। क्या यह?

उत्तर

4

कोई सीधा तरीका नहीं है, लेकिन आप static_visitor templating का उपयोग करके बहुत संक्षिप्त बना सकते हैं।

बढ़ावा डॉक्स से संशोधित:

struct boo_generic : public boost::static_visitor<> 
{ 
    template <typename T> 
    void operator()(T & operand) const 
    { 
     operand.boo(); 
    } 
}; 

अब आप यह कर सकते हैं:

struct fn_generic : public boost::static_visitor<> 
{ 
    fn_generic(void (IBase::fn)()) : fn_(fn) {} 
    template<T> void operator() (T & op) const { op.*fn(); } 
} 
:

boost::apply_visitor(boo_generic(), v); 

दरअसल आप इस सामान्यीकरण कर सकते हैं अपने आधार वर्ग के एक समारोह सूचक लेने के लिए

फिर आप कर सकते हैं:

boost::apply_visitor(boo_generic(IBase::boo), v); 

या ऐसा कुछ - मुझे शायद मेरा फ़ंक्शन पॉइंटर सिंटैक्स गलत हो गया है, लेकिन उम्मीद है कि आपको यह विचार मिल जाएगा।

संबंधित मुद्दे