2012-11-10 29 views
6

से अधिक प्राथमिकता क्यों है, मैं निम्नलिखित कोड में एक व्यवहार देख रहा हूं जिसे मैं समझ नहीं पा रहा हूं। बात यह है कि अगर मैं दोनों में से किसी की तरह operator() के दूसरे अधिभार की घोषणा के बाद:boost :: संस्करण - एक टेम्पलेट पैरामीटर को एक स्थिर स्ट्रिंग पैरामीटर

bool operator()(T other) const 
bool operator()(const T &other) const 

कार्यक्रम का उत्पादन होता है:

स्ट्रिंग

लेकिन निम्नलिखित अगर मैं का उपयोग घोषणा:

bool operator()(T &other) const 

आउटपुट होगा:

अन्य प्रकार

किसी कृपया समझा क्यों operator()(const string &other) उत्तरार्द्ध मामले में बुलाया जा रहा है ना?

#include "boost/variant/variant.hpp" 
#include "boost/variant/apply_visitor.hpp" 

using namespace std; 
using namespace boost; 

typedef variant<string, int> MyVariant; 


class StartsWith 
    : public boost::static_visitor<bool> 
{ 
public: 
    string mPrefix; 
    bool operator()(const string &other) const 
    { 
     cout << "string" << endl; 
     return other.compare(0, mPrefix.length(), mPrefix) == 0; 
    } 
    template<typename T> 
    bool operator()(T &other) const 
    { 
     cout << "other type" << endl; 
     return false; 
    } 
    StartsWith(string const& prefix):mPrefix(prefix){} 
}; 

int main(int argc, char **argv) 
{ 
    MyVariant v(string("123456")); 
    apply_visitor(StartsWith("123"), v); 
    return 0; 
} 

उत्तर

5

आपके पास const समस्या है।

आप apply_visitor पर कॉन्स्ट ऑब्जेक्ट नहीं पारित कर रहे हैं - इसलिए ऑब्जेक्ट सदस्यों को लागू विज़िटर को पास नहीं किया जाता है। तो आपके मामले में यह string& है - स्ट्रिंग प्रकार का संदर्भ। यह टेम्पलेट इसके लिए सटीक मिलान है:

template<typename T> 
bool operator()(T &other) const 

तो यह चुना गया है। इस समारोह सटीक मिलान नहीं है - यह छोड़ दिया जाता है:

bool operator()(string &other) const 

तो यह, चुना जाएगा के बाद से गैर टेम्पलेट समारोह टेम्पलेट एक से पहले माना जाता है:

bool operator()(const string &other) const 
बेशक

अगर आपको लगता है कि ऑपरेटर प्रदान करते हैं।

तो समाधान है: या तो आपके आगंतुक में विधि है जो स्ट्रिंग संदर्भ (स्थिरांक नहीं) लेता है प्रदान करते हैं - या लागू करने के लिए स्थिरांक संस्करण पारित ...

पहले समाधान - स्ट्रिंग ऑपरेटर से स्थिरांक निकालें:

bool operator()(/*const*/ string &other) const 
//    ^^^^^^^^^ remove it 

: - सामान्य आगंतुक को स्थिरांक विनिर्देशक जोड़ने

const MyVariant& cv = v; 
apply_visitor(StartsWith("123"), cv); 
//        ^^ const object passed here 

तीसरा समाधान: -

दूसरा समाधान स्थिरांक वस्तु पारित

template<typename T> 
bool operator()(const T &other) const 
//    ^^^^^ 

समाधान 1 और 3 समाधान 2 से बेहतर हैं - आपको अपने संस्करण के निरंतर विज़िटर को पास करना चाहिए, जब संकलक को उचित फ़ंक्शन का चयन करना होता है तो इसका मजबूत अर्थ होता है।

+0

एक प्रकार के सनकी के रूप में, मैं कहूंगा कि ** तीसरा ** समाधान ** सर्वोत्तम ** है, जैसा कि: ** कॉन्स्ट-सही ** है। यदि आप इसे संशोधित नहीं कर रहे हैं तो गैर-कॉन्स्ट संदर्भ द्वारा पैरामीटर लेने का कोई कारण नहीं है। –

+0

@MatthieuM। इस मामले में आप सही हैं।मैंने 'टी एंड एक्स 'का उल्लेख नहीं किया - शायद यह सबसे अच्छा होगा - लेकिन' एस एंड टी 'और' कॉन्स टी 'के बीच अंतर पर चर्चा करने वाले कई एसओ पोस्ट हैं इसलिए मैं यहां इस अनावश्यक मिश्रण को नहीं बनाना चाहता था ... – PiotrNycz

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

  • कोई संबंधित समस्या नहीं^_^