मैं C ++ 11 समर्थन के लिए कैसे जांच करूं?


104

यदि संकलनकर्ता C ++ 11 की कुछ विशेषताओं का समर्थन करता है तो संकलन-समय पर पता लगाने का कोई तरीका है? उदाहरण के लिए, कुछ इस तरह:

#ifndef VARIADIC_TEMPLATES_SUPPORTED

#error "Your compiler doesn't support variadic templates.  :("

#else

template <typename... DatatypeList>
class Tuple
{
    // ...
}

#endif

2
आपके पास "assert_variadic_template_support.hpp" नामक एक हेडर हो सकता है जिसे आप शामिल कर सकते हैं और कुछ के भीतर ऐसा कर सकते हैं template <typename... Test> struct compiler_must_support_variadic_templates;। एक सिंटैक्स त्रुटि जल्दी से समस्या को प्रकट करेगी। (एक तरफ के रूप में, एक उचित त्रुटि संदेश बहुत बेहतर है।)
GManNickG

इस समस्या को हल करने का 'सही' तरीका एक कॉन्फ़िगर परीक्षण है।
जोसेफ गार्विन

जवाबों:


125

एक निरंतर नाम है __cplusplusजिसे C ++ संकलक को C ++ मानक के संस्करण पर सेट किया जाना चाहिए समर्थित यह देखें

#if __cplusplus <= 199711L
  #error This library needs at least a C++11 compliant compiler
#endif

यह दृश्य स्टूडियो 2010 SP1 में 199711L पर सेट है, लेकिन मुझे नहीं पता कि क्या विक्रेता इसे पहले से ही बढ़ाने के लिए इतने बोल्ड होंगे यदि उनके पास सभी C ++ 11 परिवर्तनों के साथ मानक C ++ लाइब्रेरी में सिर्फ (आंशिक) कंपाइलर-स्तरीय समर्थन हो। ।

इसलिए, एक अन्य उत्तर में उल्लिखित बूस्ट के परिभाषित होने का एकमात्र एकमात्र तरीका है, उदाहरण के लिए, C ++ 11 थ्रेड और मानक के अन्य विशिष्ट भागों के लिए समर्थन।


37
C ++ 11 का मान सेट करता __cplusplusहै 201103L। यह 2011 मानक के लिए पूर्ण अनुरूपता का दावा करता है; यह आपको आंशिक अनुरूपता या संकलक एक्सटेंशन के बारे में नहीं बताता है। यदि __cplusplusसेट किया गया है 201103L, तो या तो कंपाइलर पूरी तरह से अनुरूप है या यह आपके पास पड़ा हुआ है। यदि यह नहीं है, तो आप वास्तव में यह नहीं बता सकते हैं कि यह किन विशेषताओं का समर्थन करता है।
कीथ थॉम्पसन

1
g ++ 4.7.x (और संभवतः नया) यह सेट करता है जब -std=c++11विकल्प निर्दिष्ट किया जाता है (साथ भी हो सकता है -std=gnu++11)। वे ऐसा करते हैं, भले ही वे पूरी तरह से विशेषता नहीं हैं (4.8 हमें बहुत करीब लाता है)। नोट - संकलक क्या समर्थन करता है और मानक पुस्तकालय में क्या उपलब्ध है के बीच एक अंतर है। 4.7.x और 4.8.x दोनों वर्तमान में रेगेक्स समर्थन याद कर रहे हैं - लेकिन यह एक पुस्तकालय है, एक संकलक सुविधा नहीं है।
नाथन एर्न्स्ट

1
मुझे आश्चर्य है कि यह स्वीकृत उत्तर क्यों नहीं है। इसके अलावा, आप अपने उत्तर को और बेहतर बनाने के लिए इस सुझाव का उपयोग कर सकते हैं , यह बहुत अच्छा है।
इरोब अल असिमी

1
@KeithThompson मेरे लिए, दोनों कोड :: ब्लाकों और विजुअल स्टूडियो का मान सेट __cplusplusकरने के लिए 199711Lके लिए सी ++ 11.
डोनाल्ड डक

3
@ डोनाल्डडक: सख्ती से बोलना, नहीं, वे नहीं करते हैं। एक संकलक जो सेट __cplusplusकरता 199711Lहै वह एक अनुरूप C ++ 11 संकलक नहीं है। संभवतः उनके पास सही व्यवहार करने के लिए विकल्प हैं।
कीथ थॉम्पसन

39

जैसा कि C ++ 11 मानक (§iso.16.8) ने कहा है :

नाम __cplusplus मूल्य को परिभाषित किया गया है 201103L जब एक सी ++ अनुवाद इकाई संकलन।

उस मैक्रो के मान से, आप जांच सकते हैं कि कंपाइलर C ++ 11 कंप्लेंट है या नहीं।

अब, यदि आप जाँचने के लिए एक मानक तरीके की तलाश कर रहे हैं कि क्या कंपाइलर C ++ 11 विशेषताओं का सबसे उपसमूह का समर्थन करता है, तो मुझे लगता है कि कोई मानक, पोर्टेबल तरीका नहीं है; अधिक जानकारी प्राप्त करने के लिए आप कंपाइलर प्रलेखन या एसटीडी लाइब्रेरी हेडर फाइलों की जांच कर सकते हैं।


2
उदाहरण के लिए, static_assert VS2010 और सभी c ++ 11 कॉपर्स में समर्थित है। इसलिए, यदि आप VS2010 (यानी> = 199711L) में एक सेट की तुलना में अधिक __cplusplus के मूल्य की जांच करते हैं, तो आप ठीक हो सकते हैं।
पाओलो एम

33

मुझे पता है कि यह एक बहुत पुराना सवाल है, लेकिन यह सवाल अक्सर देखा जा सकता है, और जवाब थोड़ा पुराना है।

C ++ 14 मानक वाले नए कंपाइलरों में C ++ 11 विशेषताओं सहित सुविधाओं की जांच करने का एक मानक तरीका है। एक व्यापक पृष्ठ https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations पर है

सारांश में, प्रत्येक सुविधा में एक मानक मैक्रो परिभाषित है जिसे आप देख सकते हैं #ifdef । उदाहरण के लिए, उपयोगकर्ता परिभाषित शाब्दिकों के लिए जाँच करने के लिए, आप उपयोग कर सकते हैं

#ifdef __cpp_user_defined_literals

1
मुझे नहीं पता था। मुझे लगता है कि यह सरल विशेषता देर से आ रही है, लेकिन फिर भी बहुत उपयोगी हो सकती है, खासकर __has_include()मैक्रो।
प्रॉपिन

22

चेक सपोर्ट C ++ 14 और अन्य के लिए। जीसीसी 5.2.1 पर परीक्षण।

#include <iostream>

int main(){
        #if __cplusplus==201402L
        std::cout << "C++14" << std::endl;
        #elif __cplusplus==201103L
        std::cout << "C++11" << std::endl;
        #else
        std::cout << "C++" << std::endl;
        #endif

        return 0;
}

17

आप इसका उपयोग कर सकते हैं:

#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
    cout << "C++11 is supported";
#else
    cout << "C++11 is not supported";
#endif

C ++ 11 के लिए, Visual Studio को छोड़कर अधिकांश कंपाइलर __cplusplusमैक्रो को इसमें सेट करते हैं 201103L, लेकिन Visual Studio का कोई भी संस्करण इसे सेट करता है, 199711Lजो C ++ 11 से पहले अन्य कंपाइलरों के लिए उपयोग किया जाने वाला मान है। यह कोड दृश्य स्टूडियो को छोड़कर सभी संकलक के लिए _cplusplusमैक्रो की तुलना करता है 201103L, और यदि संकलक विज़ुअल स्टूडियो है, तो यह जांचता है कि क्या विज़ुअल स्टूडियो का संस्करण बाद में 2015 की तुलना में है, विज़ुअल स्टूडियो का पहला संस्करण जो पूरी तरह से C ++ 11 का समर्थन करता है (विज़ुअल के लिए) स्टूडियो 2015, _MSC_VERमैक्रो का मूल्य है 1900, इस उत्तर को देखें )।


1
यह उत्तर गलत है। g++ -std=c++98जीसीसी 4.8 के साथ, यह गलत तरीके से प्रिंट करता है C++11 is supported
अंक

1
@pts क्षमा करें, बस एक टाइपो। इसे अब ठीक किया जाना चाहिए।
डोनाल्ड डक

7

यदि आप Boost.Config का उपयोग नहीं करना चाहते हैं और ऐसे कंपाइलरों के लिए परीक्षण करने की आवश्यकता है जो C ++ 11 का समर्थन करते हैं तो स्थिरांक के मूल्य की जांच __cplusplusकरेंगे। हालाँकि, एक संकलक C ++ 11 मानक की अधिकांश लोकप्रिय विशेषताओं का समर्थन कर सकता है, फिर भी यह संपूर्ण विशिष्टताओं का समर्थन नहीं करता है। यदि आप विशिष्ट विज़ुअल स्टूडियो कंपाइलरों के लिए समर्थन सक्षम करना चाहते हैं जो अभी तक C ++ 11 विनिर्देशों के अनुरूप नहीं हैं, तो निम्न कोड स्निपेट का उपयोग करें जो विजुअल स्टूडियो 2013 में संकलन की अनुमति देता है:

#if defined(_MSC_VER)
#   if _MSC_VER < 1800 
#       error This project needs atleast Visual Studio 2013
#   endif
#elif __cplusplus <= 199711L
#   error This project can only be compiled with a compiler that supports C++11
#endif

विजुअल स्टूडियो के लिए कंपाइलर के संस्करणों की एक पूरी सूची प्रदान की जाती है कि कैसे पता लगाया जाए कि मैं विजुअल स्टूडियो 2008 के साथ कोड संकलन कर रहा हूं


6

पारंपरिक लिनक्स / यूनिक्स दुनिया में, ऑटोकॉन्फ़ का उपयोग पारंपरिक रूप से पुस्तकालयों और संकलक सुविधाओं और बगों की उपस्थिति के लिए परीक्षण करने के लिए किया जाता है, जो उन्हें एक config.h में रखता है जो आप अपनी फ़ाइलों में आवश्यकतानुसार उपयोग करते हैं।


2
हां ऑटोकॉन्फ़ का उपयोग सुविधाओं के लिए परीक्षण करने के लिए किया जा सकता है, लेकिन आपको इसे असफलता या सफलताओं के लिए उपयुक्त मैक्रो उत्पन्न करना चाहिए जिसे बाद में ऊपर दिए गए कोड द्वारा परीक्षण किया जा सकता है। तो अपने आप में यह उत्तर कोई जानकारी नहीं जोड़ता है।
मार्टिन यॉर्क

3
@ लोकीअस्तारी: ऐसा नहीं है कि ऑटोकॉनफ कैसे काम करता है। ऑटोकॉन्फ़ मैक्रोज़ प्रदान करता है कि आपके पास आपकी कॉन्फ़िगर स्क्रिप्ट है एक परीक्षण स्रोत फ़ाइल संकलित करें और संकलन की सफलता के आधार पर #define को 0 या 1 पर सेट करें। डाइवर्सक्यूबा 23 का जवाब यह बताता है कि ओपी वास्तविक समस्या के लिए एक उप-अपनाने के समाधान तक पहुंच रहा है।
जोसेफ गार्विन


1

जब आपका चेक C ++ 11 लाइब्रेरी उपलब्धता (भाषा की सुविधा नहीं) के लिए है, उदाहरण के लिए <array>हेडर, आप कर सकते हैं #if __has_include(<array>)

कभी-कभी जाँच करते हैं #if __cplusplus >= 201103L आपको पता चलता है कि आप C ++ 11 का उपयोग करते हैं लेकिन Xcode में मानक लाइब्रेरी संस्करण सेटिंग जैसी अन्य सेटिंग्स अभी भी नई लाइब्रेरी उपलब्ध नहीं हो सकती हैं (उनमें से अधिकांश अलग-अलग नामों में उपलब्ध हैं <tr1/array>)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.