2015-03-04 11 views
8

मैं boost::swap के बराबर बनाना चाहता हूं और अपने पर्यावरण में, मानक शीर्षलेख शामिल कर सकते हैं या शामिल नहीं किए जा सकते हैं। परियोजना लाइसेंसिंग और अन्य सामान के आधार पर।
मैं गार्ड डिटेक्टरों द्वारा संरक्षित कोड के भाग बनाना चाहता हूं:क्या पोर्टेबल का पता लगाने का कोई तरीका है कि मैक्रोज़ का उपयोग करके मानक हेडर शामिल किया गया है?

चलिए एक संकलन इकाई पर विचार करें।
परियोजना विशिष्ट, आगे लिखा संभावित शामिल हैं:

#include <algorithm> // (or <utility> for C++11 projects) 

परियोजना कोड में बाद में मेरे स्वैप उपयोगिता हैडर से शामिल हैं:

namespace MyCompany 
{ 
    template<class T1, class T2> 
    void swap(T1& left, T2& right) 
    { 
    #ifdef _ALGORITHM_ // you get the idea. 
     std::swap(left, right); 
    #else 
     // fallback impl 
    #endif 
    } 
} 

सरलीकृत मैं क्योंकि हम ADL चाल के विवरण के बारे में बात नहीं कर रहे हैं यहां, लेकिन इसमें शामिल हो जाएगा।
मैं क्या बात कर रहा हूँ के संदर्भ के लिए यहाँ , लेकिन यह इस सवाल का कोई वास्ता नहीं है:
http://www.boost.org/doc/libs/1_57_0/boost/core/swap.hpp

तो इस सवाल के बारे में है, मैं कैसे मानक हेडर शामिल किए जाने पता लगा सकते हैं? _ALGORITHM_ गार्ड हेडर प्रदान किए गए विजुअल स्टूडियो में मौजूद है, लेकिन मैंने कहीं भी http://www.cplusplus.com/reference/algorithm/ पर पढ़ा है कि इसमें कोई मैक्रो होना चाहिए जिसे मैं जांच सकता हूं।

(अंतिम नोट: इस सवाल एक छोटा सा XY पक्षपाती है क्या मैं सच में चाहते std::swap समारोह, नहीं शीर्षलेख की उपस्थिति का पता लगाने के लिए है।।)

+0

तो क्या आप रिवर्स चाहते हैं? फॉलबैक के रूप में एक विशेष स्वैप का उपयोग करने के लिए? –

+0

मान लें, एक सम्मेलन के रूप में, हमारे कोडबेस के ग्राहक MyCompany :: स्वैप को डिफ़ॉल्ट स्वैप फ़ंक्शन के रूप में उपयोग करेंगे, वैसे ही उपयोगकर्ताओं को व्यापक रूप से बढ़ावा दिया गया है :: स्वैप। हालांकि, उस विशेष स्वैप के कार्यान्वयन, टीडी और टी 2 प्रकारों को एसडीडी :: स्वैप के विशेषज्ञता के साथ स्वैप किए जाने के मामले में आंतरिक रूप से std :: स्वैप का उपयोग कर सकते हैं। लेकिन यदि मानक शीर्षलेख इस बिंदु पर शामिल नहीं हैं (क्योंकि मेरी उपयोगिता में कठोर लाइसेंसिंग नियमों के संबंध में उन्हें शामिल नहीं किया जाएगा), मैं इसे पहचानना चाहता हूं और कभी भी std :: swap को कॉल नहीं करना चाहता हूं। –

+3

मैं आपके इरादे का सम्मान करता हूं लेकिन इससे लंबे समय तक मुश्किल-से-ट्रैक-डाउन बग की ओर जाता है; क्लाइंट का कोड चुपचाप व्यवहार को बदल सकता है कि वे 'शामिल करें या नहीं, और आपको क्लाइंट सपोर्ट अनुरोध –

उत्तर

4

एक विकल्प आप इसे करना है अपने विकल्पों की तुलना में "खराब मिलान" अधिभारित करें। फिर, केवल अगर वे पहले से मौजूद नहीं है अपने संस्करण का चयन किया जाएगा:

#if 0 
#include <algorithm> 
using std::swap; 
#endif 

template <typename T> 
struct ForceLessSpecialized { 
    typedef T TYPE; 
}; 

template <typename T> 
void swap (T &, typename ForceLessSpecialized<T>::TYPE &) { 
} 

void bar() { 
    int i; 
    swap (i, i); 
} 

क्या हो रहा है:

दो उम्मीदवार समारोह टेम्पलेट विशेषज्ञताओं देखते हैं जब, संकलक प्रदर्शन "समारोह टेम्पलेट्स के आंशिक आदेश "('03 14.5.5.2)। यह जांचता है कि एक टेम्पलेट के फ़ंक्शन टेम्पलेट पैरामीटर का उपयोग दूसरे विशेषज्ञ के लिए किया जा सकता है।

प्रत्येक टेम्प्लेट के लिए हम डमी मापदंडों T1 और T2 इस्तेमाल करेंगे और हम इन प्रकार का उपयोग डमी तर्क सूची बनाने के:

// std::swap argument list 
(T1 & , T1 &) 

// our swap argument list 
(T2 &, typename ForceLessSpecialized<T2>::TYPE &) 

हमारे स्वैप std::swap से डमी तर्कों का उपयोग विशेषता देता है:

Deduction from First parameter: T == T1 
Deduction from Second parameter: Non Deduced Context 

घटाया TT1 है और कटौती सफल हुई है।

हमारे स्वैप के लिए डमी तर्कों का उपयोग std::swap विशेषता देता है:

Deduction from First parameter: T == T2 
Deduction from Second parameter: T == ForceLessSpecialized<T2>::TYPE 

T के लिए deduced प्रकार ही नहीं हैं, और इसलिए इस कटौती विफलता माना जाता है।

इसलिए, std::swap की संश्लेषित तर्क हमारे टेम्पलेट विशेषज्ञ करने के लिए इस्तेमाल किया जा सकता है, लेकिन हमारे टेम्पलेट का संश्लेषित तर्क std::swap विशेषज्ञ करने के लिए इस्तेमाल नहीं किया जा सकता। std::swap को अधिक विशिष्ट के रूप में देखा जाता है और इसलिए आंशिक ordernig जीतता है।

+0

अरे, यह बहुत अच्छा काम है। निश्चित रूप से मानक से लेने के लिए एक अच्छा पढ़ा। 14.5.5.2 कक्षाओं को संदर्भित करता है, वास्तविक अनुच्छेद 14.5.6.2 है, लेकिन इसके लिए एक लिंक है। धन्यवाद :) यह मजाकिया है क्योंकि कल मैंने हर्ब सटर के "फंक्शन टेम्पलेट्स का विशेषज्ञ क्यों नहीं" पर पढ़ा था। http://www.gotw.ca/publications/mill17.htm अच्छी तरह से पढ़ें –

+0

@ v.oddou: जैसा कि आप हाल के मानकों में पैराग्राफ को इंगित करते हैं 14.5.6.2 है, मैं '03 मानक का उपयोग कर रहा था यह 14.5.5.2 के रूप में है। –

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

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