আমি অনুমান করি না, তবে আমি নিশ্চিত করতে চাই। সেখানে কোনো ব্যবহার কি const Foo&&
, যেখানে Foo
একটি বর্গ আর কী লিখব?
আমি অনুমান করি না, তবে আমি নিশ্চিত করতে চাই। সেখানে কোনো ব্যবহার কি const Foo&&
, যেখানে Foo
একটি বর্গ আর কী লিখব?
উত্তর:
এগুলি মাঝে মাঝে উপকারী। সি ++ 0x খসড়া নিজেই এগুলিকে কয়েকটি জায়গায় ব্যবহার করে, উদাহরণস্বরূপ:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
উপরের দুটি ওভারলোডগুলি নিশ্চিত করে যে অন্য ref(T&)
এবং cref(const T&)
ফাংশনগুলি মূল্যের সাথে আবদ্ধ না হয় (যা অন্যথায় সম্ভব হবে)।
হালনাগাদ
আমি স্রেফ অফিসিয়াল স্ট্যান্ডার্ড এন 3290 পরীক্ষা করেছি , যা দুর্ভাগ্যক্রমে সর্বজনীনভাবে উপলভ্য নয় এবং এটিতে 20.8 ফাংশন অবজেক্টস [ ফাংশন.বজেক্টস ] / পি 2 রয়েছে:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
তারপরে আমি সর্বাধিক সাম্প্রতিক পোস্টের সি ++ 11 খসড়াটি চেক করেছিলাম, যা সর্বজনীনভাবে উপলব্ধ, N3485 , এবং 20.8 ফাংশন অবজেক্টস [ ফাংশন.অবজেক্টস ] / পি 2 তে এখনও এটি বলে:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
const T&&
ব্যবহার করা হয়?
const T&&
প্রতিরোধ কারো বোকার মত ফর্মের স্পষ্ট টেমপ্লেট args ব্যবহার ref<const A&>(...)
। এটি কোনও ভয়ঙ্কর দৃ strong় যুক্তি নয়, তবে const T&&
ওভারের T&&
ব্যয়টি বেশ ন্যূনতম।
কনস্ট কনভুল্য রেফারেন্স (এবং এর জন্য নয় =delete
) পাওয়ার শব্দার্থবিজ্ঞানের কথাটি হল:
নিম্নলিখিত ব্যবহারের ক্ষেত্রে আইএমএইচওর পক্ষে কনস্ট্যান্ডের বিষয়ে যথাযথ রেফারেন্সের জন্য একটি ভাল ব্যবহারের মামলা হতে পারে , যদিও ভাষা এই পদ্ধতির না নেওয়ার সিদ্ধান্ত নিয়েছে ( মূল এসও পোস্টটি দেখুন )।
এটি সাধারণত ব্যবহার করার পরামর্শ দেওয়া হবে make_unique
এবং make_shared
তবে উভয়ই unique_ptr
এবং shared_ptr
কাঁচা পয়েন্টার থেকে তৈরি করা যেতে পারে। উভয় কনস্ট্রাক্টর মান দ্বারা পয়েন্টার পেতে এবং এটি অনুলিপি। উভয়ই অনুমতি দেয় (অর্থাত্ এই অর্থে: প্রতিরোধ করবেন না ) মূল পয়েন্টারটির ধারাবাহিকতা ব্যবহার তাদের কাছে কনস্ট্রাক্টরে পৌঁছেছে।
নিম্নলিখিত কোডটি দ্বৈত ফ্রি সহ সংকলন এবং ফলাফল :
int* ptr = new int(9);
std::unique_ptr<int> p { ptr };
// we forgot that ptr is already being managed
delete ptr;
উভয়ই unique_ptr
এবং shared_ptr
উপরোক্ত প্রতিরোধ করতে পারে যদি তাদের প্রাসঙ্গিক নির্মাণকারীরা কাঁচা পয়েন্টারটি কনস্টের মূল্য হিসাবে যেমন প্রত্যাশা করে তবে এটির জন্য unique_ptr
:
unique_ptr(T* const&& p) : ptr{p} {}
কোন ক্ষেত্রে উপরের ডাবল ফ্রি কোডটি সংকলন করবে না, তবে নিম্নলিখিতগুলি নিম্নলিখিতটি করবে:
std::unique_ptr<int> p1 { std::move(ptr) }; // more verbose: user moves ownership
std::unique_ptr<int> p2 { new int(7) }; // ok, rvalue
নোট করুন যে ptr
এটি সরানোর পরেও ব্যবহার করা যেতে পারে, সুতরাং সম্ভাব্য বাগটি সম্পূর্ণরূপে যায় না। তবে ব্যবহারকারীর যদি std::move
এইরকম বাগ কল করার প্রয়োজন হয় তবে এটি সাধারণ নিয়মের মধ্যে পড়ে: সরানো হয়েছে এমন কোনও সংস্থান ব্যবহার করবেন না।
একজন জিজ্ঞাসা করতে পারেন: ঠিক আছে, তবে কেন T*
কনস্ট&& p
?
কারণটি সহজ, unique_ptr
কনস্ট পয়েন্টার থেকে তৈরি করার অনুমতি দেওয়া । মনে রাখবেন যে const rvalue রেফারেন্স শুধু চেয়ে বেশি জেনেরিক হয় rvalue রেফারেন্স হিসাবে এটিকে স্বীকার করলে উভয় const
এবং non-const
। সুতরাং আমরা নিম্নলিখিত অনুমতি দিতে পারেন:
int* const ptr = new int(9);
auto p = std::unique_ptr<int> { std::move(ptr) };
এটি কেবলমাত্র আমরা যদি বিচার সংক্রান্ত রেফারেন্সটি আশা করি (সংকলন ত্রুটি: কনস্ট রাল্যুকে মূল্যকে বেঁধে রাখতে পারে না ) go
যাইহোক, এই জাতীয় জিনিস প্রস্তাব করতে খুব দেরী হয়েছে। তবে এই ধারণাটি কনস্টের কাছে কোনও মূল্যের রেফারেন্সের যুক্তিসঙ্গত ব্যবহার উপস্থাপন করে ।
এগুলি অনুমোদিত এবং এমনকি ফাংশনগুলির উপর ভিত্তি করে র্যাঙ্কিং করা হয় const
, তবে যেহেতু আপনি কনস্টের অবজেক্টের দ্বারা উল্লেখ করেছেন তা সরানো যায় না const Foo&&
, সেগুলি কার্যকর নয়।
const T&, T&, const T&&, T&&
স্ট্যান্ড :: রেফারেন্স ছাড়াও , স্ট্যান্ডার্ড লাইব্রেরি একই উদ্দেশ্যে স্ট্যান্ড :: as_const এ কনস্ট রুল্যু রেফারেন্সও ব্যবহার করে।
template <class T>
void as_const(const T&&) = delete;
মোড়কের মান পাওয়ার সময় এটি স্ট্যান্ড :: বিকল্পে রিটার্ন মান হিসাবেও ব্যবহৃত হয়:
constexpr const T&& operator*() const&&;
constexpr const T&& value() const &&;
পাশাপাশি স্ট্যান্ডে :: পান :
template <class T, class... Types>
constexpr const T&& get(const std::variant<Types...>&& v);
template< class T, class... Types >
constexpr const T&& get(const tuple<Types...>&& t) noexcept;
মোটা মানটি অ্যাক্সেস করার সময় মানটি বিভাগের সাথে সাথে মোড়কের দৃ const়তা বজায় রাখার জন্য এটি সম্ভবত।
এটি একটি ত্রুটি তৈরি করে যে কনস্ট রাল্যুয়েলের রিফ-কোয়েডড ফাংশনগুলিকে মোড়ানো বস্তুর উপর ডাকা যেতে পারে। এটি বলেছিল, আমি কনস্ট রুল্যু রেফারফুল কোয়েস্টড ফাংশনগুলির কোনও ব্যবহার জানি না।
আমি এমন পরিস্থিতিতে ভাবতে পারি না যেখানে এটি সরাসরি কার্যকর হবে তবে এটি পরোক্ষভাবে ব্যবহার করা যেতে পারে:
template<class T>
void f(T const &x) {
cout << "lvalue";
}
template<class T>
void f(T &&x) {
cout << "rvalue";
}
template<class T>
void g(T &x) {
f(T());
}
template<class T>
void h(T const &x) {
g(x);
}
টি মধ্যে ছ হয় টি const, তাই চ এর এক্স একটি টি const && হয়।
এটি একটি comile ভুলবশত সম্ভবত এই ফলাফল হল চ (যখন এটি সরানো বা অবজেক্ট ব্যবহার করার চেষ্টা করে), কিন্তু চ (তাই একটি rvalue-সুত্র গ্রহণ করতে পারে খুব সহজ হিসেবে rvalue পরিবর্তন ছাড়া যে এটি lvalues উপর বলা যায় না উদাহরণস্বরূপ)।
const&&
খুব গুরুত্বপূর্ণ, যদিও তিনি তা বলেন না: youtube.com/watch?v=JhgWFYfdIho#t=54m20s