প্রেরণা নিজেই কাগজে দেখা যায় ।
শর্তসাপেক্ষে নির্মাতাদের তৈরি করার প্রয়োজন রয়েছে। এটি, আপনি চান:
pair<string, string> safe() {
return {"meow", "purr"}; // ok
}
pair<vector<int>, vector<int>> unsafe() {
return {11, 22}; // error
}
পূর্বেরটি ঠিক আছে, যারা নির্মাতারা অন্তর্নিহিত। তবে আধুনিকগুলি খারাপ হবে, যারা নির্মাতারা explicit
। সি ++ 17 (বা ধারণাগুলি সহ সি ++ 20) দিয়ে, এই কাজটি করার একমাত্র উপায় দুটি নির্মাণকারীর লেখা - একটি explicit
এবং একজন নয়:
template <typename T1, typename T2>
struct pair {
template <typename U1=T1, typename U2=T2,
std::enable_if_t<
std::is_constructible_v<T1, U1> &&
std::is_constructible_v<T2, U2> &&
std::is_convertible_v<U1, T1> &&
std::is_convertible_v<U2, T2>
, int> = 0>
constexpr pair(U1&&, U2&& );
template <typename U1=T1, typename U2=T2,
std::enable_if_t<
std::is_constructible_v<T1, U1> &&
std::is_constructible_v<T2, U2> &&
!(std::is_convertible_v<U1, T1> &&
std::is_convertible_v<U2, T2>)
, int> = 0>
explicit constexpr pair(U1&&, U2&& );
};
এগুলি প্রায় সম্পূর্ণ নকল - এবং এই নির্মাতাদের সংজ্ঞাটি অভিন্ন হবে।
এর মাধ্যমে explicit(bool)
, আপনি কেবলমাত্র একটি একক নির্মাণকারী লিখতে পারেন - নির্মাণের শর্তাধীন স্পষ্ট অংশের সাথে কেবল স্থানীয়- explicit
স্পেসিফায়ারে স্থানীয়করণ করেছেন :
template <typename T1, typename T2>
struct pair {
template <typename U1=T1, typename U2=T2,
std::enable_if_t<
std::is_constructible_v<T1, U1> &&
std::is_constructible_v<T2, U2>
, int> = 0>
explicit(!std::is_convertible_v<U1, T1> ||
!std::is_convertible_v<U2, T2>)
constexpr pair(U1&&, U2&& );
};
এই উদ্দেশ্যটির সাথে আরও ভাল মিলছে, লেখার জন্য অনেক কম কোড এবং ওভারলোড রেজোলিউশনের সময় সংকলকটির জন্য কম কাজ (যেহেতু এর মধ্যে বেছে নিতে কম কনস্ট্রাক্টর রয়েছে)।
tuple
এই বৈশিষ্ট্যটির মতো শর্তসাপেক্ষে সুস্পষ্ট নির্মাতাদের বাস্তবায়ন করা অনেক সহজ হয়ে যায় ।