मैंने उस समग्र सूची पर ध्यान दिया एसटीडी की initalization :: वेक्टर प्रदर्शन प्रारंभ कॉपी जब चाल अधिक लागू है। एक ही समय में, कई emplace_backs मुझे क्या चाहिए।
मैं केवल एक टेम्पलेट फ़ंक्शन लिखने के इस अपूर्ण समाधान के साथ आ सकता हूं init_emplace_vector
। यह केवल गैर-स्पष्ट एकल-मूल्य के लिए इष्टतम है निर्माणकर्ताओं के , हालांकि।
template <typename T, typename... Args>
std::vector<T> init_emplace_vector(Args&&... args)
{
std::vector<T> vec;
vec.reserve(sizeof...(Args)); // by suggestion from user: eerorika
(vec.emplace_back(std::forward<Args>(args)), ...); // C++17
return vec;
}
सवाल
क्या मुझे वास्तव में stel को आरंभ करने के लिए emplace_back का उपयोग करने की आवश्यकता है :: यथासंभव कुशलता से वेक्टर?
// an integer passed to large is actually the size of the resource
std::vector<large> v_init {
1000, // instance of class "large" is copied
1001, // copied
1002, // copied
};
std::vector<large> v_emplaced;
v_emplaced.emplace_back(1000); // moved
v_emplaced.emplace_back(1001); // moved
v_emplaced.emplace_back(1002); // moved
std::vector<large> v_init_emplace = init_emplace_vector<large>(
1000, // moved
1001, // moved
1002 // moved
);
उत्पादन
क्लास large
कॉपी / मूव्स (नीचे कार्यान्वयन) और इसलिए मेरे प्रोग्राम का आउटपुट के बारे में जानकारी देता है:
- initializer
large copy
large copy
large copy
- emplace_back
large move
large move
large move
- init_emplace_vector
large move
large move
large move
बड़े वर्ग का कार्यान्वयन
मेरा कार्यान्वयन large
केवल एक प्रतिलिपि योग्य / चल प्रकार है जो एक बड़े संसाधन को रखता है जो प्रतिलिपि / चाल पर चेतावनी देता है।
struct large
{
large(std::size_t size) : size(size), data(new int[size]) {}
large(const large& rhs) : size(rhs.size), data(new int[rhs.size])
{
std::copy(rhs.data, rhs.data + rhs.size, data);
std::puts("large copy");
}
large(large&& rhs) noexcept : size(rhs.size), data(rhs.data)
{
rhs.size = 0;
rhs.data = nullptr;
std::puts("large move");
}
large& operator=(large rhs) noexcept
{
std::swap(*this, rhs);
return *this;
}
~large() { delete[] data; }
int* data;
std::size_t size;
};
संपादित करें
रिजर्व का उपयोग करके, कोई प्रतिलिपि या चाल नहीं है। केवल large::large(std::size_t)
कंस्ट्रक्टर को लगाया जाता है। सच्ची भावना।
std::array
।
operator=
जो स्रोत को नष्ट कर देता काफी असामान्य है और अप्रत्याशित समस्याएं पैदा कर सकता है।
init_emplace_vector
के साथ सुधार किया जा सकता हैvec.reserve(sizeof...(Args))
operator=
स्रोत को नष्ट नहीं करता है। यह कॉपी-स्वैप मुहावरा है।
std::initializer_list
।