2016-09-03 9 views
13

से पहले परिभाषित नहीं किए गए फ़ंक्शन/विधि को परिभाषित करें, मैं अभी तक सी ++ 11 का उपयोग नहीं करता, इसलिए मैंने अपने द्वारा to_string(whatever) फ़ंक्शंस लिखा। अगर वे अस्तित्व में नहीं हैं तो उन्हें केवल संकलित किया जाना चाहिए। अगर मैं सी ++ 11 पर स्विच करता हूं, तो उन्हें छोड़ दिया जाना चाहिए। मेरे पास ऐसा कुछ है:सी ++

#ifndef to_string 

string to_string(int a){ 
    string ret; 
    stringstream b; 
    b << a; 
    b >> ret; 
    return ret; 
} 

string to_string(double a){ 
    string ret; 
    stringstream b; 
    b << a; 
    b >> ret; 
    return ret; 
} 

#endif 

यह स्पष्ट रूप से काम नहीं करता है। क्या ऐसा कुछ संभव है और यदि हां, तो कैसे?

+0

यह काम करता है पूर्व सी ++ 11, http://cpp.sh/86ldr –

+0

@ArnavBorborah खैर देखें, ऐसा नहीं होना चाहिए काम। 'std :: to_string' सी ++ 11 चीज – xinaiz

+0

व्यक्तिगत रूप से मुझे लगता है कि यह एक बहुत ही खराब अभ्यास है, और इस प्रश्न का कोई अच्छा जवाब नहीं है। सी ++ मानक 'to_string' साबित नहीं करता है, लेकिन 'std :: to_string', जो बहुत अलग है। इसका मतलब है कि, यदि आपका मानक इसका समर्थन नहीं करता है तो आप 'std :: to_string' का उपयोग नहीं कर सकते हैं। अब फिर से सोचें - आइए मान लें कि आप पहले से ही C++ 11 का उपयोग करते हैं। अब क्या?यदि आप स्वीकार्य उत्तर से मैक्रो का उपयोग करते हैं, तो क्या आप अपने शेष जीवन के लिए 'std :: to_string' के बजाय इसका उपयोग करेंगे? बहुत, बहुत बुरा विचार। – xinaiz

उत्तर

14

यह namespace अस्तित्व का मुख्य उद्देश्य है।

मेरे सुझाव है एक उचित नाम स्थान में अपने व्यक्तिगत कार्य, जैसे कुछ शामिल करने के लिए है:

namespace myns { 
    std::string to_string(...) { 
    // ... 
    } 
    // etc... 
} 

यह आदेश भविष्य संघर्ष समस्याओं से बचने के लिए मौलिक है।

बाद में, जब आप उस फ़ंक्शन का उपयोग करने जा रहे हैं, तो आप MACRO प्रतिस्थापन के साथ उचित फ़ंक्शन का चयन कर सकते हैं।

कुछ की तरह:

#if (__cplusplus >= 201103L) 
    #define my_tostring(X) std::to_string(X) 
#else 
    #define my_tostring(X) myns::to_string(X) 
#endif 

नोट __cplusplus एक pre-defined macro जो मानक संस्करण के बारे में संकलन में जानकारी शामिल है।


संपादित करें:
कुछ कम "हिंसक", यह मानक संस्करण के अनुसार कि विशेष समारोह के लिए उचित नाम स्थान का चयन करेंगे:

#if (__cplusplus >= 201103L) 
    using std::to_string; 
#else 
    using myns::to_string; 
#endif 

// ... somewhere 
to_string(/*...*/); // it should use the proper namespace 
+2

'#if (__cplusplus> = 201103L) 'मुझे वही चाहिए जो मुझे चाहिए। धन्यवाद दोस्त। – MaestroGlanz

+6

# मैक्रो को परिभाषित करने के बजाय, 'if ifff 'ब्लॉक की प्रत्येक शाखा में' ns' :: to_string' का उपयोग करके उपयुक्त 'रखें। आपके कंपाइलर नाम स्थान पर कम हिंसा। – Spencer

9

परीक्षण कर सकते हैं नहीं है कि क्या वे इस तरह के रूप में परिभाषित किया है, लेकिन आप भाषा के संस्करण की जाँच कर सकते हैं: (। वहाँ पूर्वनिर्धारित संकलक मैक्रो here का एक उपयोगी संग्रह है)

#if __cplusplus < 201103L 

0

Boost.Config है कुछ macros यह जांचने के लिए कि C++ 11 सुविधाएं समर्थित/उपयोग की जाती हैं या नहीं।

+0

हालांकि मुझे इस सूची में 'to_string' फ़ंक्शंस के लिए मैक्रो दिखाई नहीं देता है। –

1

आप एक के अंदर अपने कार्यों डाल सकते हैं मैक्रो, इस तरह:

#ifndef to_string 
#define to_string 

//.... 

#endif 

फिर, दूसरी फ़ाइल में, इसे लिखें:

#if __cplusplus >= 201103L 
    #undef to_string 
#else 
    #define to_string 
#endif 
+1

कोड को यह जांचने की आवश्यकता नहीं है कि 'to_string' परिभाषित किया गया है या नहीं; '# undef' का उपयोग उन नामों के साथ किया जा सकता है जिन्हें परिभाषित नहीं किया गया है। –

+0

इसे साफ़ करने के लिए धन्यवाद, इसे ठीक करेगा –

2

आप इस बात को ध्यान में रखते हुए SFINAE के साथ खेल सकते हैं कि टेम्पलेट वाले पर गैर-टेम्पलेट ओवरलोड को प्राथमिकता दी जाती है। इस में संकलित दोनों पूर्व C++ 11 और C++ 11:

#include <sstream> 
#include <string> 
#include <iostream> 

using namespace std; 

namespace my { 
    template <bool V, class T> 
    struct enable_if { 
    }; 

    template <class T> 
    struct enable_if<true, T> { 
     typedef T type; 
    }; 

    template <class T1, class T2> 
    struct is_same { 
     static const bool value = false; 
    }; 

    template <class T> 
    struct is_same<T, T> { 
     static const bool value = true; 
    }; 
} 

template <class T> 
typename my::enable_if<my::is_same<T, int>::value 
         || my::is_same<T, double>::value, string>::type 
    to_string(T const& a) { 
    string ret; 
    stringstream b; 
    b << a; 
    b >> ret; 
    return ret; 
} 

int main() { 
    cout << to_string(2) << endl; 
    cout << to_string(3.4) << endl; 
}