मेरे पास डेमो उद्देश्यों के लिए एडीएल के लिए दो स्निपेट हैं। दोनों स्निपेट को वीसी 10, जीसीसी & आउरा सी ++ कंपाइलर्स द्वारा संकलित किया गया है, और परिणाम तीनों के लिए समान हैं।एडीएल को 'std namespace' में किसी फ़ंक्शन पर प्राथमिकता क्यों लेती है लेकिन उपयोगकर्ता द्वारा परिभाषित नेमस्पेस में फ़ंक्शन के बराबर होती है?
< 1> एक उपयोगकर्ता परिभाषित नाम स्थान के निर्देशों का उपयोग के खिलाफ ADL:
#include <algorithm>
namespace N
{
struct T {};
void swap(T,T) {}
}
namespace M
{
void swap(N::T,N::T) {}
}
int main()
{
using M::swap;
N::T o1,o2;
swap(o1,o2);
}
संकलित परिणाम:
error C2668: 'M::swap' : ambiguous call to overloaded function
could be 'void M::swap(N::T,N::T)'
or 'void N::swap(N::T,N::T)' [found using argument-dependent lookup]
यह ADL के रूप में की उम्मीद है सामान्य देखने परिणाम पर प्राथमिकता नहीं ले करता है प्लस एडीएल द्वितीय श्रेणी का नागरिक नहीं है, एडीएल खोज परिणाम सामान्य (गैर एडीएल) unquailfied लुकअप के साथ संघीय है। यही कारण है कि हमारे पास अस्पष्टता है।
< 2> एसटीडी नाम स्थान के निर्देशों का उपयोग के खिलाफ ADL:
#include <algorithm>
namespace N
{
struct T {};
void swap(T,T) {} //point 1
}
namespace M
{
void swap(N::T,N::T) {}
}
int main()
{
using std::swap;
N::T o1,o2;
swap(o1,o2);
}
यह एक ठीक संकलित करता है।
परिणाम संकलक एडीएल परिणाम (यह std :: स्वैप का उदाहरण लेता है) का चयन करता है, जिसका अर्थ है 'पॉइंट 1' पर N::swap()
कहा जाएगा। केवल जब 'बिंदु 1' की अनुपस्थिति में (कहें कि क्या मैं उस पंक्ति पर टिप्पणी करता हूं), संकलन इसके बजाय std::swap
पर गिरावट का उपयोग करेगा।
नोट इस तरह से कई स्थानों पर std::swap
को ओवरराइट करने के तरीके के रूप में उपयोग किया गया है। लेकिन मेरा सवाल यह है कि, एडीएल को 'std namespace' (case2) पर प्राथमिकता क्यों दी जाती है लेकिन उपयोगकर्ता द्वारा परिभाषित नेमस्पेस फ़ंक्शन (केस 1) के बराबर माना जाता है?
क्या सी ++ मानक में एक पैराग्राफ है जो ऐसा कहता है?
============================================== ====================================उपयोगी उत्तरों पढ़ने के बाद संपादित करें, दूसरों के लिए सहायक हो सकता है।
तो मैंने अपने स्निपेट को tweaked किया हैअब अस्पष्टता चली गई है और संकलन ओवरलोडिंग करते समय अनुपूरक रूप से Nontemplate फ़ंक्शन पसंद करते हैं!
#include <algorithm>
namespace N
{
struct T {};
void swap(T,T) {}
}
namespace M
{
template<class T>
void swap(N::T,N::T) {}
}
int main()
{
using M::swap;
N::T o1,o2;
swap(o1,o2); //here compiler choose N::swap()
}
मैंने अपने स्निपेट को भी tweaked किया है 2. बस अस्पष्टता को मजाक के लिए प्रकट करने के लिए!
#include <algorithm>
namespace N
{
struct T {};
template<class _Ty> inline
void swap(_Ty& _Left, _Ty& _Right)
{
_Ty _Tmp = _Move(_Left);
_Left = _Move(_Right);
_Right = _Move(_Tmp);
}
}
namespace M
{
void swap(N::T,N::T) {}
}
int main()
{
using std::swap;
N::T o1,o2;
swap(o1,o2);
}
जीसीसी और comeau दोनों अस्पष्टता कहना अपेक्षा के अनुरूप:
"std::swap" matches the argument list, the choices that match are:
function template "void N::swap(_Ty &, _Ty &)"
function template "void std::swap(_Tp &, _Tp &)"
BTW VC10 बेवकूफ हमेशा की तरह इस एक पास ठीक है जब तक मैं 'का उपयोग कर std :: स्वैप' को दूर करते हैं।
बस थोड़ा अधिक लिखने के लिए: सी ++ अधिक भार मुश्किल हो सकता है (30+ C++ मानक पेज), लेकिन appendlix B में की वहाँ एक बहुत पठनीय 10 पेज है ...
सब अच्छा करने के लिए धन्यवाद इनपुट, अब यह स्पष्ट है।
उल्लेखनीय बात यह है कि एडीएल * नाम लुकअप * से संबंधित है, और नाम लुकअप में "प्राथमिकता" की कोई धारणा नहीं है। –
@ केरेकस्क: मुझे लगता है कि डेविड नाम लुकअप चरण के बाद बात कर रहा था जबकि ओवरलोडिंग रिज़ॉल्यूशन में, जो सबसे अच्छा मैच चुनने के बारे में है। – Gob00st