ध्यान रहे मोज़ाज़ 314
यहाँ जेनेरिक std::algorithm
कॉलिंग के प्रभावों का एक अनुकरण है std::swap
, और उपयोगकर्ता नामस्थान std में अपनी स्वैप प्रदान करते हैं। जैसा कि यह एक प्रयोग है, इस सिमुलेशन के namespace exp
बजाय का उपयोग करता है namespace std
।
// simulate <algorithm>
#include <cstdio>
namespace exp
{
template <class T>
void
swap(T& x, T& y)
{
printf("generic exp::swap\n");
T tmp = x;
x = y;
y = tmp;
}
template <class T>
void algorithm(T* begin, T* end)
{
if (end-begin >= 2)
exp::swap(begin[0], begin[1]);
}
}
// simulate user code which includes <algorithm>
struct A
{
};
namespace exp
{
void swap(A&, A&)
{
printf("exp::swap(A, A)\n");
}
}
// exercise simulation
int main()
{
A a[2];
exp::algorithm(a, a+2);
}
मेरे लिए यह प्रिंट आउट:
generic exp::swap
यदि आपका कंपाइलर कुछ अलग प्रिंट करता है तो यह टेम्प्लेट के लिए "दो-चरण लुकअप" को सही ढंग से लागू नहीं कर रहा है।
यदि आपका कंपाइलर अनुरूप है (C ++ 98/03/11 में से किसी में), तो यह वही आउटपुट देगा जो मैं दिखाता हूं। और उस स्थिति में आप जो डरते हैं वही होगा, होता है। और अपने swap
नामस्थान std
( exp
) में डालने से ऐसा होने से नहीं रोका।
डेव और मैं दोनों समिति सदस्य हैं और एक दशक से मानक के इस क्षेत्र में काम कर रहे हैं (और हमेशा एक-दूसरे के साथ समझौते में नहीं)। लेकिन यह मुद्दा लंबे समय से सुलझा हुआ है, और हम दोनों इस बात पर सहमत हैं कि इसे कैसे सुलझाया गया है। इस क्षेत्र में अपने स्वयं के जोखिम पर डेव के विशेषज्ञ की राय / जवाब की अवहेलना करें।
C ++ 98 प्रकाशित होने के बाद यह समस्या सामने आई। 2001 के बारे में डेव और मैंने इस क्षेत्र में काम करना शुरू किया । और यह आधुनिक समाधान है:
// simulate <algorithm>
#include <cstdio>
namespace exp
{
template <class T>
void
swap(T& x, T& y)
{
printf("generic exp::swap\n");
T tmp = x;
x = y;
y = tmp;
}
template <class T>
void algorithm(T* begin, T* end)
{
if (end-begin >= 2)
swap(begin[0], begin[1]);
}
}
// simulate user code which includes <algorithm>
struct A
{
};
void swap(A&, A&)
{
printf("swap(A, A)\n");
}
// exercise simulation
int main()
{
A a[2];
exp::algorithm(a, a+2);
}
आउटपुट है:
swap(A, A)
अपडेट करें
एक अवलोकन किया गया है कि:
namespace exp
{
template <>
void swap(A&, A&)
{
printf("exp::swap(A, A)\n");
}
}
काम करता है! तो क्यों नहीं इस्तेमाल करते हैं?
इस मामले पर विचार करें कि आपका A
वर्ग टेम्पलेट है:
// simulate user code which includes <algorithm>
template <class T>
struct A
{
};
namespace exp
{
template <class T>
void swap(A<T>&, A<T>&)
{
printf("exp::swap(A, A)\n");
}
}
// exercise simulation
int main()
{
A<int> a[2];
exp::algorithm(a, a+2);
}
अब यह फिर से काम नहीं करता है। :-(
तो आप swap
नामस्थान एसटीडी में रख सकते हैं और यह काम कर सकता है। लेकिन आपको इस बात के लिए याद रखना होगा कि जब आपके पास कोई खाका हो तो उस मामले के लिए नाम स्थान swap
में रखें । और चूंकि दोनों ही मामलों अगर तुम डाल काम करेंगे में के नाम स्थान है, यह (और सिखाने दूसरों के लिए) बस कर कि एक तरह से करने के लिए सिर्फ याद करने के लिए आसान है।A
A<T>
swap
A