2010-01-05 41 views
7

इसे सुरक्षित myvect.size() memcopy है * sizeof (foo) एक सरणी में एकC++ std :: जोड़ी, std :: वेक्टर और memcopy

std::vector<std::pair<T1, T2> > myvect 

के पहले तत्व की memoryadress से बाइट्स

struct foo{ 
    T1 first; 
    T2 second; 
} 

की सरणी वेक्टर के आकार के रूप में तत्वों की एक ही नंबर के साथ आवंटित किया जाता है तो क्या होगा?

धन्यवाद

+1

std :: इस जोड़ी को एक struct है, मानक का कहना है संकलक, लेआउट हालांकि क्रम बनाए रखा जाना चाहिए निर्धारित करता है एसटीडी के उदाहरण में इतना :: जोड़ी आपका कंपाइलर इष्टतम संरेखण के लिए प्रत्येक चार के बाद 3-बाइट पैडिंग लगाने का निर्णय ले सकता है, इसलिए आप संगत स्मृति लेआउट - कहानी का अंत नहीं मान सकते हैं। –

उत्तर

8

नहीं, एक क्लास वाली T1 और T2std::pair<T1, T2> रूप में एक ही लेआउट या संरेखण इसकी गारंटी नहीं है, कम से कम सी ++ 98 में (के बाद से std::pair एक पॉड प्रकार नहीं है)। कहानी सी ++ 0x में अलग हो सकती है।

+0

लेकिन std :: जोड़ी सिर्फ कोई पीओडी नहीं है क्योंकि इसमें उपयोगकर्ता परिभाषित कन्स्ट्रक्टर है, नहीं? और यह स्मृति लेआउट पर कुछ नहीं बदलना चाहिए - या यह करता है? – Mat

+0

सी ++ 98 में, कार्यान्वयन को पीओडी प्रकार बनाम गैर-पीओडी प्रकारों के लिए एक अलग लेआउट का उपयोग करने की अनुमति है। सी ++ 0x में, यदि मुझे सही याद है, तो रचनाकारों के प्रकारों के लिए एक विशेष पदनाम है, लेकिन कोई आधार वर्ग, वर्चुअल फ़ंक्शन या नॉनट्रिविअल सदस्य नहीं हैं। मुझे इसका नाम याद नहीं है, लेकिन विचार यह है कि इस तरह के प्रकार 'memcpy'able होने के लिए काफी सरल हैं। –

+1

@ क्रिस: मानक-लेआउट, लेकिन एक मानक-लेआउट वर्ग * जरूरी * कॉपी करने के लिए सुरक्षित नहीं है, इसका मतलब है (प्रभाव में) कि कंपाइलर ने कोई बुरा आश्चर्य नहीं डाला है। एक आरएआईआई कक्षा जिसमें एक ढेर-आवंटित वस्तु के लिए सूचक होता है, यह असाइनमेंट पर विनाश और क्लोन पर मुक्त होता है, मानक लेआउट है लेकिन पीओडी नहीं है, और शायद इसे memcpy के साथ कॉपी नहीं किया जाना चाहिए। –

0

सामान्य रूप से, नहीं। कुछ प्लेटफॉर्म/कंपाइलर्स/एसटीएल कार्यान्वयन पर यह हो सकता है, लेकिन वैसे भी ऐसा न करें। आप दोनों जोड़ी <> और वेक्टर <> के कार्यान्वयन विवरण पर भरोसा करेंगे।

मैंने स्वयं वेक्टर <> एक संगत सरणी होने पर भरोसा करने का पाप किया है। इसके लिए, मैं गहराई से पश्चाताप करता हूं। लेकिन जोड़ी <> ... बस नहीं कहो।

+5

वास्तव में वेक्टर <> आईएस एक संगत सरणी होने की गारंटी है। –

+0

@Fred: कृपया उद्धरण दें? –

+0

यह बहुत अधिक स्वीकार्य है कि 'std :: vector ' संगत है (मुझे लगता है कि सी ++ के भविष्य के संस्करण इस तरह निर्दिष्ट करेंगे), और 'vecs [0]' आकार 'vec.size() 'के आकार के रूप में प्रयोग योग्य होना चाहिए। । लेकिन, 'std :: pair' जैसे गैर-पीओडी प्रकारों पर' memcpy' करना जोखिम भरा है, हां। –

4

सवाल आप नहीं पूछा का जवाब शायद std::transform है:

struct pairToFoo { 
    // optionally this can be a function template. 
    // template<typename T1, typename T2> 
    foo operator()(const std::pair<T1,T2> &p) const { 
     foo f = {p.first, p.second}; 
     return f; 
    } 
}; 

std::transform(myvect.begin(), myvect.end(), myarray, pairToFoo()); 

या std::copy, लेकिन foo एक operator= पैरामीटर के रूप में एक जोड़ी लेने दे। यह आपको फिर से लिख सकते हैं foo हालांकि मान लिया गया है:

struct foo { 
    T1 first; 
    T2 second; 
    foo &operator=(const std::pair<T1,T2> &p) { 
     first = p.first; 
     second = p.second; 
     return *this; 
    } 
}; 

std::copy(myvect.begin(), myvect.end(), myarray); 
+0

'std :: transform() 'कुछ ऐसा है जो मुझे कभी याद नहीं है। कभी। शायद अब मैंने सार्वजनिक रूप से कहा है, यह कभी-कभी मेरे सिर में चलेगा। –

+1

'std :: transform' जो आप मानचित्र और ज़िप के बजाय प्राप्त करते हैं। तो हो सकता है कि हर बार जब आप ट्रांसफॉर्म के बारे में भूल जाते हैं, तो आप हास्केल में प्रासंगिक फ़ंक्शन को फिर से लिखते हैं, तो आपको याद होगा। अगर केवल हास्केल लिखने से बचने के लिए। –

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