2008-11-17 18 views
112

के रूप में चिह्नित करें मेरे पास एक इंटरफेस में एक तरीका है जिसे मैं पोर्टेबल सी ++ से हटाना चाहता हूं। जब मैंने इस सब के लिए गुगल किया तो मुझे माइक्रोसॉफ्ट विशिष्ट समाधान मिला; #pragma deprecated और __declspec(deprecated)सी ++ मार्क

एक दूसरा पुरस्कार समाधान यदि एक एमएसवीसी और जीसीसी समाधान के लिए होगा।
धन्यवाद

उत्तर

129

सी ++ 14 में, आप [[deprecated]] विशेषता का उपयोग करके बहिष्कृत किए गए फ़ंक्शन को चिह्नित कर सकते हैं (अनुभाग 7.6.5 [dcl.attr.deprecated] देखें)।

विशेषता-टोकनdeprecated नाम और संस्थाओं जिसका उपयोग अभी भी अनुमति दी है चिह्नित करने के लिए इस्तेमाल किया जा सकता है, लेकिन किसी कारण से हतोत्साहित किया जाता है।

उदाहरण के लिए, निम्नलिखित समारोह foo अब मान्य नहीं है:

[[deprecated("Replaced by bar, which has an improved interface")]] 
void foo(int); 

संदेश करना होगा:

[[deprecated]] 
void foo(int); 

यह संदेश का वर्णन करता है क्यों नाम या संस्था पदावनत किया गया था प्रदान करने के लिए संभव है एक स्ट्रिंग शाब्दिक हो।

अधिक जानकारी के लिए, “Marking as deprecated in C++14” देखें।

+0

क्या आप मैक्रो में [[बहिष्कृत]] का उपयोग कर सकते हैं? – Zammbi

+1

@Zammbi आपको सक्षम होना चाहिए, क्योंकि मैक्रो को संकलन से पहले प्रीप्रोसेसर द्वारा संभाला जाता है। [[बहिष्कृत]] प्रकट होना चाहिए (और संकलक आउटपुट से संबंधित चेतावनियां दें) जहां मैक्रो का मूल्यांकन किया जाता है। –

21

जीसीसी में आप विशेषता इस तरह पदावनत के साथ अपने समारोह की घोषणा कर सकते हैं: जब कि समारोह एक ग फ़ाइल में प्रयोग किया जाता है

void myfunc() __attribute__ ((deprecated)); 

यह एक संकलन समय चेतावनी ट्रिगर किया जाएगा।

आप पोर्टेबल परियोजनाओं यह आप कुछ बिंदु पर प्लेटफार्मों की एक श्रृंखला के लिए preprocessed विकल्प के एक वर्ग की जरूरत है कि लगभग अपरिहार्य है के साथ काम http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html

4

पर "निदान pragmas" के अंतर्गत अधिक जानकारी पा सकते हैं। #ifdef यह #ifdef और इसी तरह से।

ऐसे खंड में आप प्रतीकों को बहिष्कृत करने के लिए एक तरह से सशर्त रूप से परिभाषित कर सकते हैं। मेरी वरीयता आमतौर पर "चेतावनी" मैक्रो को परिभाषित करने के लिए होती है क्योंकि अधिकांश टूलचेन्स कस्टम कंपाइलर चेतावनियों का समर्थन करते हैं। फिर आप बहिष्करण आदि के लिए एक विशिष्ट चेतावनी मैक्रो के साथ आगे बढ़ सकते हैं समर्पित बहिष्करण विधियों का समर्थन करने वाले प्लेटफ़ॉर्म के लिए आप चेतावनियों के बजाय इसका उपयोग कर सकते हैं।

116

इस चाल करना चाहिए:

#ifdef __GNUC__ 
#define DEPRECATED(func) func __attribute__ ((deprecated)) 
#elif defined(_MSC_VER) 
#define DEPRECATED(func) __declspec(deprecated) func 
#else 
#pragma message("WARNING: You need to implement DEPRECATED for this compiler") 
#define DEPRECATED(func) func 
#endif 

... 

//don't use me any more 
DEPRECATED(void OldFunc(int a, float b)); 

//use me instead 
void NewFunc(int a, double b); 

हालांकि, अगर एक समारोह वापसी प्रकार जैसे अपने नाम में एक अल्पविराम का है आप समस्याओं का सामना करेंगे std::pair<int, int> क्योंकि इस प्रीप्रोसेसर द्वारा व्याख्या की गई मैक्रो में 2 तर्कों को पारित करने के रूप में व्याख्या की जाएगी। उस स्थिति में आपको रिटर्न प्रकार टाइप करना होगा।

संपादित करें: सरल (लेकिन संभवतः कम व्यापक रूप से संगत) संस्करण here

+5

# आतंक के बजाय, बेहतर होगा # डिफ्रैक्टेड (func) func – CesarB

+0

@CesarB: मैं असहमत हूं; अगर कोई त्रुटि नहीं थी, तो यह देखने का कोई तरीका नहीं होगा कि कुछ अप्रत्याशित हुआ। – foraidt

+1

mxp: बहिष्करण केवल एक चेतावनी है, और इसलिए मैं कहूंगा कि एक चेतावनी है कि यह समर्थित नहीं है, आपको बस इतना ही चाहिए। –

39

यहाँ मेरी 2008 answer का एक सरलीकृत संस्करण है:

#ifdef __GNUC__ 
#define DEPRECATED __attribute__((deprecated)) 
#elif defined(_MSC_VER) 
#define DEPRECATED __declspec(deprecated) 
#else 
#pragma message("WARNING: You need to implement DEPRECATED for this compiler") 
#define DEPRECATED 
#endif 

//... 

//don't use me any more 
DEPRECATED void OldFunc(int a, float b); 

//use me instead 
void NewFunc(int a, double b); 
+10

आप कैसे [[बहिष्कृत]] 'अपने बहिष्कृत मैक्रोज़ कैसे करते हैं? :-) –

+1

मैं उन दो उत्तरों के बीच कोई महत्वपूर्ण अंतर नहीं देख सकता। आपने इसे दूसरी बार क्यों पोस्ट किया? –

+3

आपको इसे फ़ंक्शन के चारों ओर लपेटने की ज़रूरत नहीं है, इसलिए यह 'अस्वीकृत शून्य foo (...) है; 'DEPRECATED (शून्य foo (...)) के बजाय;' – dshepherd

2

यहाँ 2018

इन दिनों के लिए एक और अधिक पूरा जवाब है, उपकरणों का एक बहुत कुछ के रूप में पदावनत तुम सिर्फ कुछ चिह्नित नहीं करने की अनुमति है, लेकिन एक संदेश भी प्रदान करें। यह आपको लोगों को बताने की इजाजत देता है जब कुछ बहिष्कृत किया गया था, और शायद उन्हें प्रतिस्थापन की ओर इंगित करें।

  • सी ++ 14 [[deprecated]]/[[deprecated(message)]] समर्थन करता है:

    अभी भी संकलक समर्थन में विभिन्न प्रकार के एक बहुत कुछ है।

  • __attribute__((deprecated)) जीसीसी 4.0+ और एआरएम 4.1+
  • __attribute__((deprecated)) और __attribute__((deprecated(message))) द्वारा समर्थित है के लिए समर्थित है: निर्धारित करके
    • जीसीसी 4.5+
    • कई compilers जो जीसीसी का छद्मवेष 4.5+ (__GNUC__/__GNUC_MINOR__/__GNUC_PATCHLEVEL__)
    • इंटेल सी/सी ++ कंपाइलर कम से कम 16 पर वापस जा रहा है (आप __GNUC__/__GNUC_MINOR__ पर भरोसा नहीं कर सकते हैं, वे इसे जीसीसी के किसी भी संस्करण में स्थापित कर सकते हैं)
    • __declspec(deprecated) 13.10 के बाद से (विजुअल स्टूडियो 2003)
    • MSVC __declspec(deprecated(message)) 14.0 के बाद से (विजुअल स्टूडियो 2005)

    तुम भी बजना के हाल के संस्करणों में [[gnu::deprecated]] उपयोग कर सकते हैं का समर्थन करता है

  • एआरएम 5.6+
  • MSVC का समर्थन करता है सी ++ 11 में, __has_cpp_attribute(gnu::deprecated) पर आधारित है।

    मैं जो मैं नवीनतम जानकारी रखना स्वचालित रूप से यह सब संभाल करने Hedley में कुछ मैक्रो है, लेकिन वर्तमान संस्करण (v2) इस तरह दिखता है:

    #if defined(__cplusplus) && (__cplusplus >= 201402L) 
    # define HEDLEY_DEPRECATED(since) [[deprecated("Since " #since)]] 
    # define HEDLEY_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]] 
    #elif \ 
        HEDLEY_GCC_HAS_EXTENSION(attribute_deprecated_with_message,4,5,0) || \ 
        HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \ 
        HEDLEY_ARM_VERSION_CHECK(5,6,0) 
    # define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) 
    # define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) 
    #elif \ 
        HEDLEY_GCC_HAS_ATTRIBUTE(deprcated,4,0,0) || \ 
        HEDLEY_ARM_VERSION_CHECK(4,1,0) 
    # define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) 
    # define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) 
    #elif HEDLEY_MSVC_VERSION_CHECK(14,0,0) 
    # define HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) 
    # define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) 
    #elif HEDLEY_MSVC_VERSION_CHECK(13,10,0) 
    # define HEDLEY_DEPRECATED(since) _declspec(deprecated) 
    # define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) 
    #else 
    # define HEDLEY_DEPRECATED(since) 
    # define HEDLEY_DEPRECATED_FOR(since, replacement) 
    #endif 
    

    मैं इसे करने के लिए एक व्यायाम के रूप में छोड़ देंगे अगर आप हेडली का उपयोग नहीं करना चाहते हैं तो मैंने *_VERSION_CHECK और *_HAS_ATTRIBUTE मैक्रोज़ से छुटकारा पाने का तरीका जानें (मैंने हेडली को काफी हद तक लिखा था इसलिए मुझे नियमित आधार पर इसके बारे में सोचना नहीं होगा)।

    यदि आप जीएलआईबी का उपयोग करते हैं, तो आप G_DEPRECATED और G_DEPRECATED_FOR मैक्रोज़ का उपयोग कर सकते हैं। वे हेडली के लोगों के रूप में मजबूत नहीं हैं, लेकिन यदि आप पहले ही जीएलआईबी का उपयोग करते हैं तो इसमें कुछ भी नहीं है।

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