2012-08-29 14 views
12

क्या फ़ंक्शन ऑब्जेक्ट ओवरलोड रिज़ॉल्यूशन के दौरान नियमित कार्यों से अलग तरीके से व्यवहार किए जाते हैं? यदि हां, तो कैसे?फ़ंक्शन ऑब्जेक्ट्स ओवरलोड रिज़ॉल्यूशन को कैसे प्रभावित करते हैं?

#include <iostream> 

namespace N 
{ 
    enum E { A, B }; 

    void bar(E mode) { std::cout << "N::bar\n"; } 
} 

template <typename... Args> 
void bar(Args&&... args) { std::cout << "global bar\n"; } 

int main() 
{ 
    bar(N::A); 
} 

यहाँ उत्पादन "N :: बार" है:

मैं जहां एक समतुल्य रूप-प्रतिदेय समारोह वस्तु के साथ एक समारोह की जगह निम्नलिखित मामले में चलाने की है कोड के अर्थ बदल दिया है। अब तक, बहुत अच्छा: एन :: बार एडीएल द्वारा पाया जा रहा है, एन :: बार और वैश्विक बार दोनों सटीक मिलान हैं, और एन :: बार को प्राथमिकता दी जाती है क्योंकि यह टेम्पलेट नहीं है।

लेकिन अगर मैं वैश्विक बार बदलें ताकि तरह, एक समारोह वस्तु होने के लिए:

#include <iostream> 

namespace N 
{ 
    enum E { A, B }; 

    void bar(E mode) { std::cout << "N::bar\n"; } 
} 

struct S 
{ 
    template <typename... Args> 
    void operator()(Args&&... args) { std::cout << "global bar\n"; } 
}; 
S bar; 

int main() 
{ 
    bar(N::A); 
} 

उत्पादन अब "वैश्विक बार" है। अंतर क्यों?

उत्तर

12

यहां महत्वपूर्ण बात यह है कि अगर एडीएल केवल यह निर्धारित करता है कि नाम फ़ंक्शन कॉल में एक फ़ंक्शन है। दूसरे मामले में, barऑब्जेक्ट पाया गया है और कोई फ़ंक्शन नहीं है, इसलिए अभिव्यक्ति bar(N::A) फ़ंक्शन कॉल नहीं है, लेकिन operator() का ऑब्जेक्ट bar पर लागू है। चूंकि यह फ़ंक्शन कॉल नहीं है, इसलिए एडीएल किक नहीं करता है और N::bar पर विचार नहीं किया जाता है।

3.4.1/3

एक अयोग्य एक समारोह कॉल 3.4.2 में वर्णित के पोस्टफ़िक्स अभिव्यक्ति के रूप में इस्तेमाल के लिए नाम देखने। [नोट: निर्धारित करने के प्रयोजनों के लिए (पार्सिंग के दौरान) क्या एक अभिव्यक्ति एक funfion कॉल के लिए एक पोस्टफिक्स-अभिव्यक्ति है, सामान्य नाम लुकअप नियम लागू होते हैं। 3.4.2 [एडीएल] में नियमों का अभिव्यक्ति की वाक्य रचनात्मक व्याख्या पर कोई प्रभाव नहीं पड़ता है।

एक और तरीका है इस पर गौर करने के लिए सूचना के लिए कि ADL अतिभारित कार्यों की सेट करने के लिए नए कार्यों जोड़ देगा है, लेकिन दूसरे उदाहरण में ऐसी कोई सेट नहीं है: देखने एक वस्तु और के एक सदस्य पाता है वस्तु कहा जाता है।

+2

आज मैंने सीखा, डेविड धन्यवाद। – ildjarn

+0

मुझे लगता है कि 3.4 पर नोट नहीं है।1/3 प्रासंगिक है, क्योंकि 'बार' * * फ़ंक्शन कॉल अभिव्यक्ति में पोस्टफिक्स-अभिव्यक्ति है (ऑपरेशन के रूप में कोई फ़ंक्शन नहीं है, लेकिन अंततः एक को कॉल कर रहा है!)। नोट में कहा गया है कि 3.4.2 "x (y)" के सिंटैक्टिक अर्थ को नहीं बदलता है - यदि यह एक फ़ंक्शन कॉल है, तो यह 3.4.2 का निर्णय लेने के लिए फ़ंक्शन कॉल को अनदेखा करता है। –

+0

@ जोहान्सचैब-लिटब: नियमित लुकअप मिलेगा कि 'बार' एक ऑब्जेक्ट है, और ऑब्जेक्ट' बार (x) 'होने के कारण उस ऑपरेटर को' ऑपरेटर() 'के अनुप्रयोग का प्रतिनिधित्व करता है। जबकि ऑपरेटर का आवेदन एक फंक्शन कॉल है, यह एक * सदस्य-फ़ंक्शन * कॉल है, और इस प्रकार एडीएल लागू नहीं होता है। –

4

3.4.2p3 देखें, जो

Let एक्स देखने अयोग्य देखने (3.4.1) द्वारा निर्मित सेट हो सकता है और वाई देखने तर्क निर्भर देखने द्वारा उत्पादित सेट हो कहते हैं (इस प्रकार के रूप में परिभाषित)। एक्स

  • ...
  • एक घोषणा न एक समारोह या एक समारोह टेम्पलेट है कि मौजूद होता है तो

तो Y खाली है।

यदि ऐसा कोई नियम नहीं होगा, तो आप सही हैं: एडीएल आपके अन्य फ़ंक्शन को ओवरलोड सेट में जोड़ देगा। वास्तव में, 13.3.1.1 पी 1 इस पर निर्भर करता है: इसमें दो शाखाएं हैं; एक फ़ंक्शन कॉल एक्सप्रेशन के लिए जहां ऑपरेंड क्लास ऑब्जेक्ट को इंगित करता है, और दूसरा एक जहां ऑपरेंड एक या अधिक फ़ंक्शंस या फ़ंक्शन टेम्पलेट्स को इंगित करता है।

+0

+1 से नीचे देखें, आपके द्वारा प्रदान किया गया उद्धरण मेरे द्वारा उद्धृत नोट का कारण है। –

+0

@ डेविड आप इसे गलत समझ रहे हैं –

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