std::vector
must initialize the values in the array somehow, which means some constructor (or copy-constructor) must be called. The behavior of vector
(or any container class) is undefined if you were to access the uninitialized section of the array as if it were initialized.
reserve()
और push_back()
का उपयोग करने का सबसे अच्छा तरीका है, ताकि कॉपी-कन्स्ट्रक्टर का उपयोग किया जा सके, डिफ़ॉल्ट-निर्माण से परहेज किया जा सके।
अपने उदाहरण कोड का उपयोग करना:
struct YourData {
int d1;
int d2;
YourData(int v1, int v2) : d1(v1), d2(v2) {}
};
std::vector memberVector;
void GetsCalledALot(int* data1, int* data2, int count) {
int mvSize = memberVector.size();
//Does not initialize the extra elements
memberVector.reserve(mvSize + count);
//Note: consider using std::generate_n or std::copy instead of this loop.
for (int i = 0; i < count; ++i) {
//Copy construct using a temporary.
memberVector.push_back(YourData(data1[i], data2[i]));
}
}
reserve()
(या resize()
) को कॉल करने में एकमात्र समस्या यह है कि आप प्रतिलिपि बनाने के लिए अक्सर कॉपी-कन्स्ट्रक्टर का आविष्कार कर सकते हैं। यदि आप सरणी के अंतिम आकार के रूप में अच्छी भविष्यवाणी कर सकते हैं, तो शुरुआत में एक बार reserve()
स्थान बेहतर होगा। यदि आप अंतिम आकार को नहीं जानते हैं, तो कम से कम प्रतियों की संख्या औसतन न्यूनतम होगी।
In the current version of C++, the inner loop is a bit inefficient as a temporary value is constructed on the stack, copy-constructed to the vectors memory, and finally the temporary is destroyed. However the next version of C++ has a feature called R-Value references (T&&
) which will help.
std :: vector
द्वारा प्रदान किया गया इंटरफ़ेस किसी अन्य विकल्प की अनुमति नहीं देता है, जो डिफ़ॉल्ट रूप से अन्य मानों को बनाने के लिए कुछ फैक्ट्री-जैसी कक्षा का उपयोग करना है। सी ++ में यह पैटर्न कैसा दिखता है इसका एक मोटा उदाहरण यहां दिया गया है:
template
class my_vector_replacement {
//...
template
my_vector::push_back_using_factory(F factory) {
//... check size of array, and resize if needed.
//Copy construct using placement new,
new(arrayData+end) T(factory())
end += sizeof(T);
}
char* arrayData;
size_t end;//Of initialized data in arrayData
};
// One of many possible implementations
struct MyFactory {
MyFactory(int* p1, int* p2) : d1(p1), d2(p2) {}
YourData operator()() const {
return YourData(*d1,*d2);
}
int* d1;
int* d2;
};
void GetsCalledALot(int* data1, int* data2, int count) {
//... Still will need the same call to a reserve() type function.
//Note: consider using std::generate_n or std::copy instead of this loop.
for (int i = 0; i < count; ++i) {
//Copy construct using a factory
memberVector.push_back_using_factory(MyFactory(data1+i, data2+i));
}
}
ऐसा करने का मतलब है कि आपको अपनी खुद की वेक्टर कक्षा बनाना है। इस मामले में यह भी जटिल है कि एक साधारण उदाहरण क्या होना चाहिए। लेकिन ऐसे समय हो सकते हैं जहां इस तरह के फैक्ट्री फ़ंक्शन का उपयोग करना बेहतर होता है, उदाहरण के लिए यदि सम्मिलन किसी अन्य मूल्य पर सशर्त है, और आपको अन्यथा बिना किसी अस्थायी रूप से कुछ महंगा अस्थायी निर्माण करना होगा, भले ही इसकी वास्तव में आवश्यकता न हो।