2011-10-04 46 views
5

Ideone testcase: http://ideone.com/lzepFकास्ट एक निरंतर अभिव्यक्ति में प्रकट नहीं कर सकते हैं

कोड:

#include <iostream> 
#include <sstream> 
#include <vector> 
#include <map> 
#include <list> 
#include <set> 

#include <stdint.h> 

template <typename T> std::ostream& write(std::ostream& os, T const& x); 
template <typename T> std::istream& read(std::istream& is, T& x); 

template <typename T, typename U> std::ostream& write(std::ostream& os, std::pair<T, U> const& rh); 
template <typename T, typename U> std::istream& read(std::istream& is, std::pair<T, U>& rh); 

template <typename T> std::ostream& writeContainer(std::ostream& os, T const& rh); 

template <typename T, typename U> std::ostream& write(std::ostream& os, std::map<T, U> const& rh); 
template <typename T, typename U> std::istream& read(std::istream& is, std::map<T, U> rh); 

template <typename T> std::ostream& write(std::ostream& os, std::vector<T> const& rh); 
template <typename T> std::istream& read(std::istream& is, std::vector<T>& rh); 

template <typename T> 
std::ostream& write(std::ostream& os, T const& x){ 
    static_assert(!std::is_pointer<T>(), "That's a pointer, you probably don't want to write that"); 
    static_assert(std::is_pod<T>(), "That's not a POD: can't write it"); 
    os.write(reinterpret_cast<const char *>(&x), sizeof(T)); 
    return os; 
} 

template <typename T> 
std::istream& read(std::istream& is, T& x){ 
    static_assert(!std::is_pointer<T>(), "That's a pointer, you probably don't want to read that"); 
    static_assert(std::is_pod<T>(), "That's not a POD: can't read it"); 
    is.read(reinterpret_cast<char *>(&x), sizeof(T)); 
    return is; 
} 

template <typename T, typename U> 
std::ostream& write(std::ostream& os, std::pair<T, U> const& rh){ 
    write(os, rh.first); 
    write(os, rh.second); 
    return os; 
} 

template <typename T, typename U> 
std::istream& read(std::istream& is, std::pair<T, U>& rh){ 
    read(is, rh.first); 
    read(is, rh.second); 
    return is; 
} 

template <typename T> 
std::ostream& writeContainer(std::ostream& os, T const& rh){ 
    uint32_t size = std::distance(rh.begin(), rh.end()); 
    write(os, size); 

    for(auto it = rh.begin(); it != rh.end(); ++it){ 
     write(os, *it); 
    } 

    return os; 
} 

template <typename T> 
std::istream& readContainer(std::istream& is, T& rh){ 
    uint32_t size; 
    read(is, size); 
    std::insert_iterator<T> it(rh, rh.end()); 

    for(uint32_t i=0; i<size; ++i) { 
     typename T::value_type x; 
     read(is, x); 
     it = x; 
    } 
    return is; 
} 

template <typename T, typename U> 
std::ostream& write(std::ostream& os, std::map<T, U> const& rh){ 
    return writeContainer(os, rh); 
} 

template <typename T, typename U> 
std::istream& read(std::istream& is, std::map<T, U> rh){ 
    return readContainer(is, rh); 
} 

template <typename T> 
std::ostream& write(std::ostream& os, std::vector<T> const& rh){ 
    return writeContainer(os, rh); 
} 

template <typename T> 
std::istream& read(std::istream& is, std::vector<T>& rh){ 
    return readContainer(is, rh); 
} 

int main(){ 
    { 
     std::stringstream s; 
     std::vector<int> x = {0, 1, 2, 3}; 
     write(s, x); 
    } 

    { 
     std::stringstream s; 
     std::map<int, int> x = {{0, 0}, {1, 2}, {2, 4}, {3, 6}}; 
     write(s, x); 
    } 

    return 0; 
} 

त्रुटियाँ:

prog.cpp: In function 'std::ostream& write(std::ostream&, const T&) [with T = unsigned int, std::ostream = std::basic_ostream<char>]': 
prog.cpp:57:2: instantiated from 'std::ostream& writeContainer(std::ostream&, const T&) [with T = std::vector<int>, std::ostream = std::basic_ostream<char>]' 
prog.cpp:92:30: instantiated from 'std::ostream& write(std::ostream&, const std::vector<T>&) [with T = int, std::ostream = std::basic_ostream<char>]' 
prog.cpp:104:13: instantiated from here 
prog.cpp:29:11: error: a cast to a type other than an integral or enumeration type cannot appear in a constant-expression 
prog.cpp:29:11: error: a cast to a type other than an integral or enumeration type cannot appear in a constant-expression 
prog.cpp: In function 'std::ostream& write(std::ostream&, const T&) [with T = int, std::ostream = std::basic_ostream<char>]': 
prog.cpp:60:3: instantiated from 'std::ostream& writeContainer(std::ostream&, const T&) [with T = std::vector<int>, std::ostream = std::basic_ostream<char>]' 
prog.cpp:92:30: instantiated from 'std::ostream& write(std::ostream&, const std::vector<T>&) [with T = int, std::ostream = std::basic_ostream<char>]' 
prog.cpp:104:13: instantiated from here 
prog.cpp:29:11: error: a cast to a type other than an integral or enumeration type cannot appear in a constant-expression 
prog.cpp:29:11: error: a cast to a type other than an integral or enumeration type cannot appear in a constant-expression 

जब से हम कोई लाइन नंबर है,: (, यह पहले write(s, x) के बारे में शिकायत करता है, और मुझे लगता है कि मुझे reinterpret_cast<const char*>(const unsigned int*) के बारे में शिकायत है लेकिन मुझे पूरा यकीन है कि कानूनी होना चाहिए।

क्या गलत हो रहा है?

+1

'std :: is_pointer ()' आदि के बजाय, यह 'std :: is_pointer :: value' नहीं होना चाहिए? –

उत्तर

5

आप is_pod और is_pointer गलत तरीके से उपयोग कर रहे हैं।

static_assert(!std::is_pointer<T>::value, "That's a pointer, you probably don't want to write that"); 
    static_assert(std::is_pod<T>::value, "That's not a POD: can't write it"); 

आप इस के साथ परीक्षण कर सकते हैं:

write(std::cout, 1); 
    int *p = 0; 
    write(std::cout, p); 
+0

लाइन संख्या थोड़ी दूर हैं, तो? जब ऐसा होता है तो नफरत है .. –

+0

@ तोमालक गेट्टल, हाँ यह थोड़ा खराब है ... – Nim

+0

मजेदार, यह gcc-4.6.1 में भी() के साथ काम करता है .. अजीब। धन्यवाद! – Nick

1

सी ++ 03 स्टैंडर्ड 5.19 "लगातार भाव", पैरा 1 कहता है:

आप निम्न करने के लिए इसे बदलने की जरूरत है

कई स्थानों पर, सी ++ को उन अभिव्यक्तियों की आवश्यकता होती है जो एक अभिन्न या गणना निरंतर मूल्यांकन करते हैं: सरणी सीमा (8.3.4, 5.3.4) के रूप में, केस एक्सप्रेशन (6.4.2), बिट-फील्ड लम्बाई (9.6) के रूप में, गणक I nitializers (7.2), स्थिर सदस्य प्रारंभकर्ता (9.4.2) के रूप में, और अभिन्न या गणना गैर प्रकार के टेम्पलेट तर्क (14.3) के रूप में।

निरंतर अभिव्यक्ति: सशर्त अभिव्यक्ति

एक अभिन्न निरंतर अभिव्यक्ति केवल शाब्दिक (2.13), प्रगणक, स्थिरांक चर या निरंतर भाव के साथ प्रारंभ अभिन्न या गणन प्रकार के स्थिर डेटा सदस्यों को शामिल कर सकते हैं (8.5) , अभिन्न या गणना प्रकारों के गैर-प्रकार के टेम्पलेट पैरामीटर, और आकार के अभिव्यक्तियों का आकार। फ़्लोटिंग अक्षर (2.13.3) केवल तभी दिखाई दे सकते हैं जब उन्हें अभिन्न या गणना प्रकारों में डाला जाता है। केवल अभिन्न या गणना प्रकारों में रूपांतरण टाइप करें। विशेष रूप से, अभिव्यक्तियों, कार्यों, वर्ग वस्तुओं, पॉइंटर्स, या संदर्भों को छोड़कर, उपयोग नहीं किया जाएगा, और असाइनमेंट, वृद्धि, कमी, फ़ंक्शन-कॉल, या अल्पविराम ऑपरेटरों का उपयोग नहीं किया जाएगा।

कोड बयान:

static_assert (std :: is_pointer(), "यह एक सूचक, तो आप शायद नहीं कि लिखना चाहते है"!); static_assert (std :: is_pod(), "यह एक पीओडी नहीं है: इसे लिख नहीं सकता");

इस नियम को तोड़ने और इसलिए संकलक शिकायत करता है।

+0

क्या यह अभी भी सी ++ 11 के लिए सच है? ओपी ने नए कोड 'जी ++' पर मूल कोड के साथ सफलता की रिपोर्ट की। –

+0

@ TomalakGeretkal: मुझे सी ++ 11 ड्राफ्ट और गेटबैक देखने दो। –

+0

@ टॉमलक गेरेक्टकल: हाँ, यह सी ++ 11 में बदल गया है, मानक अब इस बाधा को लागू नहीं करता है, लगता है कि जीसीसी सी ++ 11 का पालन करने के लिए पर्याप्त तेज़ी से रहा है। –

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