2013-02-06 13 views
12

मैं उस प्रश्न को नहीं ढूंढ पाया, और यह एक वास्तविक समस्या है जिसका सामना कर रहा हूं।कैसे std :: वेक्टर <अहस्ताक्षरित चार> वेक्टर को नकल के बिना <char> कन्वर्ट करने के लिए?

मैं एक फ़ाइल लोड हो रहा है उपयोगिता कि std::vector<unsigned char> रिटर्न पूरी फ़ाइल सामग्री युक्त है। हालांकि, प्रसंस्करण समारोह char की contiguos सरणी की आवश्यकता है (और है कि बदला नहीं जा सकता है - यह एक पुस्तकालय समारोह है)। चूंकि प्रसंस्करण फ़ंक्शन का उपयोग करने वाली कक्षा किसी भी तरह से डेटा की एक प्रति संग्रहीत करती है, इसलिए मैं इसे vector<char> के रूप में स्टोर करना चाहता हूं। यहां कोड है जो थोड़ा अधिक चित्रकारी हो सकता है।

std::vector<unsigned char> LoadFile (std::string const& path); 

class Processor { 
    std::vector<char> cache; 
    void _dataOperation(std::vector<char> const& data); 

public: 
    void Process() { 
     if (cache.empty()) 
      // here's the problem! 
      cache = LoadFile("file.txt"); 

     _dataOperation(cache); 
    } 
}; 

यह कोड संकलित नहीं करता है, क्योंकि (स्पष्ट रूप से) कोई उचित रूपांतरण नहीं है। हम निश्चित रूप से सुनिश्चित कर सकते हैं कि अस्थायी वेक्टर एक ही मात्रा में स्मृति (आईओयू sizeof(char) == sizeof(unsigned char))

बेवकूफ समाधान अस्थायी की सामग्री पर पुनरावृत्ति करना होगा और प्रत्येक चरित्र को कास्ट करना होगा। मुझे पता है कि सामान्य मामले में, operator= (T&&) कहा जाएगा।

मेरी स्थिति में यह रूपांतरण पुनर्व्याख्या करना सुरक्षित है, क्योंकि मुझे यकीन है कि मैं केवल ASCII वर्ण पढ़ने जा रहा हूँ कर रहा हूँ। किसी अन्य चरित्र को _dataOperation में वैसे भी पकड़ा जाएगा।

तो, मेरा प्रश्न है: अस्थायी वेक्टर को सही तरीके से और सुरक्षित रूप से कैसे परिवर्तित करना है जिसमें कोई प्रतिलिपि शामिल नहीं है?

यदि यह संभव नहीं है, मैं असुरक्षित noncopying बजाय कॉपी करने का सुरक्षित तरीका पसंद करेंगे। मैं भी LoadFile बदलने या तो vector<char> या vector<unsigned char> वापस जाने के लिए कर सकता है।

+1

यदि आप '_dataOperation' के कोड को नियंत्रित करते हैं, तो आप लंबे समय तक लंबे समय तक खुश रहेंगे यदि आप इसे 'वेक्टर ' लेते हैं। दुर्भाग्य से – zwol

+0

@Zack, मैं नहीं करता। यह एक पुस्तकालय समारोह है। मैं सवाल संपादित करूंगा। –

+0

कोई _safe_ रास्ता –

उत्तर

6

सी ++ 11 में, [basic.lval] p10 कहते हैं,

एक कार्यक्रम निम्नलिखित प्रकार व्यवहार है में से एक के अलावा अन्य के glvalue के माध्यम से एक वस्तु की संग्रहीत मूल्य तक पहुँचने के लिए प्रयास करता है अपरिभाषित:

  • ...
  • एक चार या अहस्ताक्षरित चार प्रकार।

(सटीक स्थान सी ++ के अन्य संस्करणों में अलग हो सकता है, लेकिन अर्थ एक ही है।)

इसका मतलब है कि आप एक vector<unsigned char> cache लेने के लिए और इसकी सामग्री रेंज [reinterpret_cast<char*>(cache.data()), reinterpret_cast<char*>(cache.data()) + cache.size()) का उपयोग कर पहुँच सकते हैं। (@Kerrek एस.बी. इस उल्लेख किया है।)

आप LoadFile की वापसी प्रकार से मिलान करने के Processor में एक vector<unsigned char> की दुकान, और _dataOperation() वास्तव में char की एक सरणी (एक const char* और एक आकार अर्थ) लेता है, तो आप जब तुम डाल सकता '_dataOperation()

हालांकि करने के लिए तर्क गुजर रहे हैं, अगर _dataOperation() एक vector<char> विशेष रूप से लेता है और आप एक vector<unsigned char> cache की दुकान है, तो आप नहीं कर सकते पास यह reinterpret_cast<vector<char>&>(cache)। (यानी @ आंद्रे पुल पूरी तरह गलत है। उसे मत सुनो।) यह एलियासिंग नियमों का उल्लंघन करता है, और संकलक 2:00 बजे अपने ग्राहकों को क्रोधित करने का प्रयास करेगा।(और यदि आपका कंपाइलर का यह संस्करण इसे प्रबंधित नहीं करता है, तो अगला संस्करण कोशिश करेगा।)

एक विकल्प है, जैसा कि आपने बताया है, टेम्पलेट LoadFile() पर और इसे वापस (या भरें) टाइप करें जो आप चाहते हैं। दूसरा परिणाम परिणाम की प्रतिलिपि बनाना है, जिसके लिए संक्षिप्त संस्करण स्रोत वेक्टर के .data() के reinterpret_cast है। [basic.fundamental] p1 का उल्लेख है कि "चरित्र प्रकारों के लिए, वस्तु प्रतिनिधित्व के सभी बिट्स मूल्य प्रतिनिधित्व में भाग लेते हैं।", जिसका अर्थ है कि आप उस reinterpret_cast के साथ डेटा खोने वाले नहीं हैं। मुझे एक फर्म गारंटी नहीं दिखाई देती है कि unsigned char का कोई पैटर्न पैटर्न reinterpret_cast'ed से char पर जाल का कारण बन सकता है, लेकिन मुझे ऐसा करने वाले किसी भी आधुनिक हार्डवेयर या कंपाइलर्स के बारे में पता नहीं है।

+0

एक पूर्ण उत्तर के लिए धन्यवाद। –

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