2015-02-19 5 views
5

नीचे मेरे पास प्रॉक्सीकॉल नामक टेम्पलेट फ़ंक्शन है, जो किसी ऑब्जेक्ट को स्वीकार करता है, एक सदस्य फ़ंक्शन और इसके तर्क। यह बस सदस्य समारोह को कॉल अग्रेषित करता है।टेम्पलेट किए गए कार्यों में कॉन्स संदर्भों का कटौती टाइप करें

मैं टेम्पलेट क्वालीफायर का उपयोग किए बिना फ़ंक्शन को कॉल करने में सक्षम होना चाहता हूं (कई तर्कों के साथ ऐसी कॉलों की कल्पना करें)। टाइप कटौती ज्यादातर काम करता है लेकिन उदाहरण के रूप में जब मैं कॉन्स्ट रेफरेंस पैरामीटर पास करने का प्रयास करता हूं तो कंपेलर (एमएसवीसी और जीसीसी 4.9 दोनों बार)।

#include <string> 

struct Widget { 
    void f(const std::string& s, bool b) {} 
}; 


template<typename T, typename... Args> 
void ProxyCall(T &obj, void(T::*method)(Args...), Args&&... args) { 
    (obj.*method)(std::forward<Args>(args)...); 
} 


int main(int argc, char* argv[]) 
{ 
    Widget w; 
    std::string s; 

    ProxyCall<Widget, const std::string&, bool>(w, &Widget::f, s, true); // OK 
    ProxyCall(w, &Widget::f, (const std::string&)s, true); // also OK 

    ProxyCall(w, &Widget::f, s, true); // ERROR: template parameter is ambiguous 
    return 0; 
} 

मेरा प्रश्न है: इतना है कि संकलक स्वचालित रूप से स्पष्ट टेम्पलेट क्वालिफायर या स्पष्ट कास्टिंग का सहारा के बिना प्रकार निकालना होगा मैं कैसे उपरोक्त कोड संशोधित कर सकते हैं। ऐसा लगता है कि यह संभव होना चाहिए कि संकलक पहले से ही जानता है कि विजेट :: एफ के हस्ताक्षर से सटीक तर्क प्रकार हैं।

+1

'टेम्पलेट शून्य प्रॉक्सीकॉल (टी एंड ओबीजे, एम विधि, Args && ... args) ' – zch

+1

या वैकल्पिक रूप से' टेम्पलेट <टाइपनाम टी, टाइपनाम ... मार्ग, टाइपनाम ... Args> शून्य प्रॉक्सीकॉल (टी & ओबीजे, शून्य (टी: : * विधि) (मार्ग ...), Args && ... तर्क) ' – zch

उत्तर

3
template<typename T, typename... Args> 
void ProxyCall(T &obj, void(T::*method)(Args...), Args&&... args) { 
    (obj.*method)(std::forward<Args>(args)...); 
} 

Args दोनों दूसरा तर्क और ProxyCall के पीछे तर्क से निष्कर्ष निकाला है।
आपके तीसरे मामले में, sconst नहीं है, Args[std::string&, bool] को घटाया गया है (संदर्भ ढहने और अग्रेषण संदर्भों के नियमों को याद करें)। हालांकि, सदस्य कार्य हस्ताक्षर स्पष्ट रूप से अलग है। इस प्रकार Args में पहले प्रकार के लिए दो अलग-अलग प्रकारों को घटाया जाता है, जिससे कटौती विफलता होती है।

इसके बजाय, दोनों पैरामीटर प्रकार और तर्क स्वतंत्र बनाने - और आगे वस्तु तर्क रेफरी-क्वालिफायर के लिए,:

template<typename T, typename F, typename... Args> 
void ProxyCall(T&& obj, F method, Args&&... args) { 
    (std::forward<T>(obj).*method)(std::forward<Args>(args)...); 
} 
संबंधित मुद्दे