2016-04-25 9 views
11

इस कोड ऐसा नहीं करता है, जो उसे करना चाहिए था:क्यों std: :(​​i) ओस्ट्रीम उपचार एक पाठ के रूप में हस्ताक्षरित/हस्ताक्षरित चार और एक पूर्णांक नहीं है?

#include <iostream> 
#include <cstdint> 

int main() 
{ 
    uint8_t small_integer; 
    std::cin >> small_integer; 
    std::cout << small_integer; 
} 

वजह साफ है: uint8_tunsigned char के लिए एक typedef है और धाराएं इस प्रकार एक पाठ के रूप में इलाज:
विजुअल C++ 2015 कार्यान्वयन

template<class _Traits> inline 
    basic_istream<char, _Traits>& operator>>(
     basic_istream<char, _Traits>& _Istr, unsigned char& _Ch) 
    { // extract an unsigned char 
    return (_Istr >> (char&)_Ch); 
    } 

और operator << के लिए char पर कास्ट के साथ एक समान कोड।

मेरे सवालों का:

  1. इस व्यवहार (स्ट्रीमिंग ऑपरेटरों इलाज पर हस्ताक्षर किए चरित्र प्रकार और कोई पूर्णांक नहीं के रूप में/अहस्ताक्षरित चार) मानक के लिए आवश्यक है? यदि यह है तो:
    1. ऐसे counterintuitive semantics के पीछे तर्क क्या है?
    2. क्या इसे दोष माना जाना चाहिए, क्या इस अर्थशास्त्र को बदलने के प्रस्ताव थे?

मैं शायद एक छोटे से स्पष्टीकरण कारण है कि मैं यह counterintuitive पर विचार जोड़ना चाहिए। हालांकि टाइप नाम में शब्द चार है, signed या unsigned भाग विशेष पूर्णांक अर्थपूर्ण निर्दिष्ट करता है और उन प्रकारों को आम तौर पर बाइट आकार वाले पूर्णांक के रूप में उपयोग किया जाता है। यहां तक ​​कि मानक int8_t/uint8_t उनके माध्यम से परिभाषित करता है।

युपीडी: सवाल unsigned char और signed char के लिए स्ट्रीमिंग ऑपरेटर भार के के व्यवहार के बारे में है।

+1

यह कष्टप्रद है। मैंने अपना खुद का to_string फ़ंक्शन का उपयोग किया है जो एक चरित्र के रूप में char का इलाज करते समय (u) int8_t पूर्णांक के रूप में व्यवहार करता है। मैंने uint8_t, int8_t, और char के लिए अलग-अलग विशेषज्ञताओं को जोड़ा क्योंकि मुझे लगता है कि यह उन तीनों के लिए बिल्कुल मान्य है जो तीन अलग-अलग प्रकार नहीं हैं। – Matt

+4

आपके प्रश्न का उत्तर नहीं है, लेकिन ['std :: byte'] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0257r0.pdf) का प्रस्ताव दिया गया है इस समस्या को दूर करो। – Praetorian

+0

@ प्रेटोरियन, जबकि यह वास्तव में एक दिलचस्प प्रस्ताव है, यह एक बिल्कुल अलग मुद्दे को संबोधित करता है। –

उत्तर

3

मानक (n3797) का कहना है निम्नलिखित:

27.7.2.2.3 basic_istream :: ऑपरेटर >>

template<class charT, class traits> 
basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>& in, charT& c); 

template<class traits> 
basic_istream<char,traits>& operator>>(basic_istream<char,traits>& in, unsigned char& c); 

template<class traits> 
basic_istream<char,traits>& operator>>(basic_istream<char,traits>& in, signed char& c); 

12 ई एफएफ ECTS: एक स्वरूपित तरह बर्ताव करता है इनपुट सदस्य (जैसा कि 27.7.2.2.1 में वर्णित है)। एक प्रेषित वस्तु के निर्माण के बाद एक वर्ण निकाला जाता है से, यदि कोई उपलब्ध है, और सी में संग्रहित है। अन्यथा, फ़ंक्शन in.setstate (failbit) में कॉल करता है।

27.7.3.6.4 चरित्र Inserter समारोह टेम्पलेट्स

// specialization 
template<class traits> 
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, char c); 

// signed and unsigned 
template<class traits> 
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, signed char c); 

template<class traits> 
basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>& out, unsigned char c); 

1 ई एफएफ ECTS: बाहर के एक फ़ॉर्मेट उत्पादन समारोह (27.7.3.6.1) के रूप में व्यवहार करता है। एक चरित्र अनुक्रम seq बनाता है। यदि सी में टाइप चार है और धारा का चरित्र प्रकार चार नहीं है, तो seq में बाहर हैं। विडेन (सी); अन्यथा seq में c शामिल हैं। 27.7.3.6.1 में वर्णित अनुसार सीक के लिए पैडिंग निर्धारित करता है। बाहर निकलता है। कॉल ओएसविड्थ (0)।

तो पहला सवाल का जवाब: हां, मानक है कि operator >> और operator << वास्तव में व्यवहार करते हैं char, unsigned char और signed char के लिए एक ही आवश्यकता है, कि वे पढ़ने/एकल वर्ण, नहीं एक पूर्णांक बारे में है। दुर्भाग्यवश, मानक क्यों नहीं समझाता है। मुझे आशा है कि किसी को 2 पर प्रकाश डाला जाएगा और 3.

1
  1. इस व्यवहार मानक के लिए आवश्यक है? यदि यह है:

आपने पहले ही इसका उत्तर दिया है। हां, मानक परिभाषित करता है कि कैसे iostreams हस्ताक्षरित और हस्ताक्षरित चार को संभालना चाहिए।

  1. इस तरह के प्रतिद्वंद्वी अर्थशास्त्र के पीछे तर्क क्या है?

क्योंकि signed char और unsigned charचरित्र प्रकार हैं, इसलिए वे हमेशा iostreams वर्गों द्वारा पात्रों के रूप में माना जाता है।

सुराग नाम में है: signed char एक हस्ताक्षरित चरित्र प्रकार है। unsigned char एक हस्ताक्षरित चरित्र प्रकार है। अन्य अभिन्न प्रकारों में int उनके नाम पर हैं (भले ही यह कभी-कभी वैकल्पिक हो, उदाहरण के लिए short और long unsigned क्रमश: short int और long unsigned int के समान हैं)।

मानक है क्योंकि यह एक डिजाइन दस्तावेज़ या C और C++ के इतिहास के लिए एक औचित्य नहीं है, यही कारण है कि यह सच है कहने की जरूरत नहीं है, यह एक विनिर्देश है।

यदि आप एक प्रकार चाहते हैं जो केवल 8 बिट्स के साथ एक पूर्णांक की तरह व्यवहार करता है तो आपको अपना खुद का निर्माण करना होगा (उदाहरण के लिए एक गणना प्रकार या एक संरचना जिसमें एक मूल्य है) और प्रासंगिक ऑपरेटर ओवरलोड को परिभाषित करें।

  1. क्या इसे दोष माना जाना चाहिए, क्या इस अर्थशास्त्र को बदलने के प्रस्ताव थे?

नहीं, मुझे ऐसा नहीं लगता। वे हमेशा चरित्र प्रकार रहे हैं और यह बदलने के लिए बहुत अधिक कोड तोड़ देगा।

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