2017-03-17 14 views
7

cppref में, मैं एक अजीब प्रकार विशेषता चेकर देखें: std::has_unique_object_representationsकिस प्रकार "std :: has_unique_object_representations" झूठी वापसी करेगा?

इसके विवरण से, मैं किसी भी प्रकार T कि std::has_unique_object_representations<T>::valuefalse है कल्पना नहीं कर सकते।

क्या कोई काउंटर उदाहरण है?

+0

यहां शब्द http://en.cppreference.com/w/cpp/types/has_unique_object_representations का तात्पर्य है कि टी को तुलनीय रूप से प्रतिलिपि बनाने की आवश्यकता है और कुछ तर्क भी देता है। –

+3

आईईईई 754-संगत फ्लोट एक counterexample हैं, क्योंकि सकारात्मक और नकारात्मक शून्य के प्रतिनिधित्व भिन्न हैं, लेकिन उनके मूल्य स्पष्ट रूप से बराबर हैं। – Fanael

+2

इसके अलावा, शून्य कुल कुल पैडिंग बिट्स के साथ किसी भी प्रकार का। – Fanael

उत्तर

9

इस विशेषता के उद्देश्य को समझना एक वस्तु "मूल्य प्रतिनिधित्व" और इसके "ऑब्जेक्ट प्रस्तुति" के बीच भेद को समझने की आवश्यकता है। मानक से:

वस्तु प्रतिनिधित्व प्रकार T की एक वस्तु की एन अहस्ताक्षरित चार वस्तुओं प्रकार T की वस्तु है, जहां एन के बराबर होती है sizeof(T) द्वारा लिया के अनुक्रम है। किसी ऑब्जेक्ट का मान प्रतिनिधित्व बिट्स का सेट है जो T प्रकार का मान रखता है। तुलनीय रूप से प्रतिलिपि बनाने योग्य प्रकारों के लिए, मान प्रतिनिधित्व ऑब्जेक्ट प्रतिनिधित्व में बिट्स का एक सेट है जो मान निर्धारित करता है, जो मूल्यों के कार्यान्वयन-निर्धारित सेट का एक अलग तत्व है।

तो ऑब्जेक्ट प्रस्तुति किसी ऑब्जेक्ट का कुल संग्रहण है। लेकिन निम्न ऑब्जेक्ट पर विचार करें:

struct T 
{ 
    char c; 
    int i; 
}; 

कई प्रणालियों पर, sizeof(T) 8 होगा। क्यों? क्योंकि int को 4-बाइट गठबंधन होना चाहिए, इसलिए संकलक c और i के बीच पैडिंग के 3 बाइट्स को सम्मिलित करता है। चूंकि वे तीन बाइट ऑब्जेक्ट के स्टोरेज (sizeof(T) पर आधारित) का हिस्सा हैं, इसलिए वे ऑब्जेक्ट के ऑब्जेक्ट प्रस्तुति का हिस्सा हैं।

लेकिन उन तीन बाइट इसके मूल्य प्रतिनिधित्व का हिस्सा नहीं हैं। यदि आपने उन बाइट्स को संशोधित किया है, तो वे c या i के मूल्यों या उनके बारे में कुछ भी प्रभावित नहीं करेंगे।

यदि आपने T के लिए ओवरलोड लिखा है, तो उन बाइट्स में परिवर्तन इसके परिणामों को प्रभावित नहीं करेंगे। जो भी मतलब है कि अगर तुमने किया था एक operator== अधिभार, यह इस तरह से लागू नहीं किया जा सकता है लिखें:

bool operator==(const T &lhs, const T &rhs) 
{ 
    return std::memcmp(&lhs, &rhs, sizeof(T)) == 0; 
} 

क्यों नहीं? क्योंकि दो T के उन पैडिंग बाइट्स के लिए अलग-अलग मान हो सकते हैं, लेकिन अभी भी c और i का वही मान है। और इस प्रकार उनके पास समान मूल्य प्रतिनिधित्व होता है और इस प्रकार समकक्ष माना जाना चाहिए।

has_unique_object_representations सच है जब T की वस्तु प्रतिनिधित्व और अपने मूल्य प्रतिनिधित्व बिल्कुल ओवरले एक दूसरे के (और T तुच्छता copyable हो)। तो, आप इस पर कब ध्यान देंगे?

आप एक सामान्यीकृत हैशिंग फ़ंक्शन लिख सकते हैं जो कि किसी भी छोटे कॉपी करने योग्य प्रकार T पर बाइट्स की सरणी के रूप में अपना मान प्रतिनिधित्व पढ़कर और उन्हें हैशिंग करके काम करता है। खैर, आप कर सकते हैं, लेकिन केवल तभी जब इस प्रकार के पैडिंग बाइट्स नहीं हैं।और यही has_unique_object_representations आपको बताता है: ऑब्जेक्ट प्रतिनिधित्व मामले में सभी बाइट्स।

यह भी ध्यान दें कि float प्रकार, यह मान आवश्यक नहीं होगा कि बाइनरी समानता और फ़्लोटिंग-पॉइंट समानता आईईईई -754 में समान नहीं है। ऐसे प्रकार जिनमें float एस शामिल हैं, यह भी आवश्यक नहीं होगा। दरअसल, कार्यान्वयन जो किसी के पूरक हस्ताक्षर पूर्णांक का उपयोग करते हैं, या जाल प्रतिनिधित्व के साथ हस्ताक्षरित पूर्णांक, इस प्रकार के लिए भी यह सच नहीं होगा।

+0

मुझे लगता है कि आप 'memcmp' कॉल में' sizeof (T) 'खो रहे हैं। –

+0

व्यवहार के समान फ्लोट वाले प्रकारों के बारे में क्या है लेकिन उपयोगकर्ता प्रकार हैं? मेरा मतलब है सिद्धांत में, मेरे पास ऐसी संरचना हो सकती है जिसमें एक यूंट 32 सदस्य हो लेकिन उस पर सभी परिचालनों को लागू करें जैसे कि यह फ़्लोट सदस्य था। दूसरे शब्दों में यह एक संरचना फ्लोट {uint32 f} होगा; सभी परिचालनों को प्रभावित किया गया ताकि फ्लोट फ्लोट में निर्मित के रूप में व्यवहार करे। इसके अलावा मुझे लगता है कि स्ट्रिंग क्लासेस इस फिट नहीं होंगे ... – NoSenseEtAl

+1

@NoSenseEtAl: ठीक है, यह एक अच्छा मुद्दा है, लेकिन कई मामलों में, ट्रिविलीपीपीबल प्रतिबंध उनको बाहर कर देगा (स्ट्रिंग केस की तरह)। आखिरकार, भले ही आपकी 'फ्लोट :: ऑपरेटर ==' कुछ बिट्स की परवाह नहीं करेगी, जहां तक ​​भाषा का संबंध है, वे अभी भी वहां हैं और वे अभी भी मायने रखते हैं। –

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