Saturday 15 May 2010

c++ - Compile-time check whether output (<<) and relational (, etc.) are available -


मैं वर्तमान में is_call_possible 3rd party code

एक सदस्य उपलब्ध है, तो समय संकलन में पता लगाने के लिए। यह उदाहरण महान काम करता है:

  #include & lt; स्ट्रिंग & gt; #include "is_call_possible.h" DEFINE_IS_CALL_POSSIBLE (is_call_possible, ऑपरेटर ()) DEFINE_IS_CALL_POSSIBLE (test_available, परीक्षण) struct फू {शून्य ऑपरेटर () (डबल) {} डबल परीक्षण (std :: स्ट्रिंग) {वापसी 0; }}; Int main (int argc, const char * argv []) {static_assert (is_call_possible & lt; फ़ू, शून्य (डबल) & gt; :: value, "err"); // सफलता static_assert (test_available & lt; Foo, डबल (std :: स्ट्रिंग) & gt; :: मूल्य, "err"); // सफल वापसी 0; }   

लेकिन इस साधारण गैर सदस्यों पर काम नहीं करता तो मैं उत्पादन और संबंधपरक ऑपरेटर के लिए भी ऐसा ही नहीं कर सकते हैं:

  DEFINE_IS_CALL_POSSIBLE ( output_available, ऑपरेटर को & lt; & lt;) // त्रुटि DEFINE_IS_CALL_POSSIBLE (less_available, ऑपरेटर को & lt;) // त्रुटि DEFINE_IS_CALL_POSSIBLE (greater_available, ऑपरेटर & gt;) // त्रुटि   

तुम मुझे सुविधाजनक 3 पार्टी कोड को इंगित कर सकते हैं (या अपना खुद का कोड)?

अंतर्निहित समाधान ("तृतीय पक्ष कोड") सी ++ 11 में कार्यान्वित किया जा सकता है यदि यह आसान है, लेकिन मुझे लगता है कि मुझे अंतर नहीं पता होगा अपने स्वयं के कोड में (तृतीय पक्ष कोड के उपयोगकर्ता के रूप में)।

सी +11 का मानना ​​है एक विकल्प, decltype संकलन समय निर्माण SFINAE साथ संयोजन के रूप में इस्तेमाल किया जा सकता करने के लिए मूल रूप से करते हैं 'अवधारणा चेकों' प्रकार पर (सी ++ 11 मानक में जाँच सही अवधारणा की कमी के बावजूद), करने के लिए देखें कि वे ऑपरेशन का समर्थन करते हैं।

(untested के रूप में मुझे एक C + + 11 संकलक A की कमी है पल [आप विंडोज़ को शाप देते हैं!], लेकिन मुझे यकीन है कि अगर कोई मौजूद है तो कोई मेरी त्रुटियों को पकड़ेगा।)

Ex।

  template & lt; typename T & gt; Struct voidify {typedef शून्य प्रकार;}; टेम्पलेट & lt; typename टी, typename यू, typename को सक्षम = शून्य & gt; स्ट्रक्चर has_operator_less {enum {value = false}; }; टेम्पलेट & lt; typename टी, टाइपनाम यू & gt; struct has_operator_less & LT; टी, यू, typename voidify & LT; decltype (std :: declval & LT; टी & gt; () के & lt; std :: declval & lt; u & gt; () // & lt; - इस 'अवधारणा' के एक ओर है) & gt; :: प्रकार & gt; {Enum {value = true}; };   

और आप इसका उपयोग सक्षम करने के लिए / std :: enable_if के साथ को निष्क्रिय उपस्थिति या ऑपरेटर के & lt के अभाव पर निर्भर है किसी भी कार्य का निर्माण; उन दो प्रकारों के लिए मौजूद है:

  टेम्पलेट & lt; typename टी, टाइपनाम यू & gt; Typename std :: enable_if & lt; has_operator_less & LT; टी, u & gt; :: मूल्य, I_am_the_result_type_of_the_function & gt; :: प्रकार I_depend_on_the_existence_of_the_less_than_operator (स्थिरांक टी & amp; एक, स्थिरांक यू एंड बी) {...}   

और एक वैकल्पिक अगर आप चाहते हैं प्रकार है कि कमी ऑपरेटर & lt समारोह के कार्यान्वयन; , तो आप सिर्फ निषेध के साथ सक्षम:

  टेम्पलेट के & lt; typename टी, typename u & gt; Typename std :: enable_if & lt; ! Has_operator_less & LT; टी, u & gt; :: मूल्य, I_am_the_result_type_of_the_function // ^ निषेध & gt ध्यान दें; :: प्रकार I_depend_on_the_existence_of_the_less_than_operator (स्थिरांक टी & amp; एक, स्थिरांक यू एंड बी) {...}   

इसलिए अब आपके पास ऐसे कार्यान्वयन हैं जो कि उन प्रकार के प्रकारों के लिए समय संकलित करने के लिए निर्धारित होते हैं और जिनके पास उन ऑपरेटर नहीं होते हैं, और यह समाधान किसी भी अन्य ऑपरेटर या फ़ंक्शन नाम या कुछ के लिए दोहराया जा सकता है । बस अवधारणा आप जाँच कर रहे हैं जगह में decltype

और इस में से कोई भी

(फिर से निर्माण से पहले एक अलग विन्यास कदम होने की आवश्यकता है।, Untested code -.- 'लेकिन बहुत यकीन है कि सही, आप सभी जानते हैं कि संपादन बटन कहां है :- P)

No comments:

Post a Comment