আমি লক্ষ্য করেছি যে স্টাড :: ভেক্টর সামগ্রিক তালিকা সূচনা করার সময় নড়াচড়া আরও প্রযোজ্য হলে অনুলিপি শুরু করে । একই সময়ে, একাধিক এমপ্ল্যাস_ব্যাকগুলি আমি যা চাই তা করে।
আমি কেবলমাত্র একটি টেম্পলেট ফাংশন লেখার এই অসম্পূর্ণ সমাধানটি নিয়ে আসতে পারি 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;
}
প্রশ্ন
স্ট্যান্ড :: ভেক্টর যথাসম্ভব দক্ষতার সাথে আরম্ভ করার জন্য আমার কি সত্যিই এমপ্লেস_ব্যাক ব্যবহার করা দরকার ?
// 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
।