সি ++ এ সংকলনকালে স্ট্রিংগুলি তৈরি এবং পরিচালনা করতে সক্ষম হওয়ায় বেশ কয়েকটি দরকারী অ্যাপ্লিকেশন রয়েছে। যদিও সি ++ তে কম্পাইল-টাইম স্ট্রিংগুলি তৈরি করা সম্ভব, প্রক্রিয়াটি খুব জটিল, কারণ স্ট্রিংটিকে অক্ষরের বিচিত্র ক্রমিক হিসাবে ঘোষণা করা দরকার, যেমন
using str = sequence<'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!'>;
স্ট্রিং কনটেনটেশন, স্ট্রারিং এক্সট্রাকশন এবং আরও অনেকের মতো অপারেশনগুলি অক্ষরের অনুক্রমের ক্রিয়াকলাপ হিসাবে সহজেই প্রয়োগ করা যেতে পারে। কম্পাইল-টাইম স্ট্রিংগুলি আরও সুবিধাজনকভাবে ঘোষণা করা সম্ভব? যদি তা না হয় তবে কী এমন কোনও প্রস্তাব রয়েছে যা সংকলন-সময়ের স্ট্রিংগুলির সুবিধাজনক ঘোষণার অনুমতি দেবে?
বিদ্যমান পদ্ধতির ব্যর্থতা কেন
আদর্শভাবে, আমরা নিম্নরূপে সংকলন-সময়ের স্ট্রিংগুলি ঘোষণা করতে সক্ষম হতে চাই:
// Approach 1
using str1 = sequence<"Hello, world!">;
বা, ব্যবহারকারী-সংজ্ঞায়িত আক্ষরিক ব্যবহার করে,
// Approach 2
constexpr auto str2 = "Hello, world!"_s;
যেখানে decltype(str2)একজন constexprকনস্ট্রাক্টর থাকবে পদ্ধতির 1 এর একটি ম্যাসেয়ার সংস্করণ বাস্তবায়ন করা সম্ভব, আপনি নিম্নলিখিতটি করতে পারেন তার সুযোগ নিয়ে:
template <unsigned Size, const char Array[Size]>
struct foo;
যাইহোক, অ্যারের বাহ্যিক সংযোগ থাকা দরকার, সুতরাং কাজ করার জন্য 1 পদ্ধতির পেতে আমাদের এই জাতীয় কিছু লিখতে হবে:
/* Implementation of array to sequence goes here. */
constexpr const char str[] = "Hello, world!";
int main()
{
using s = string<13, str>;
return 0;
}
বলা বাহুল্য, এটি খুব অসুবিধাজনক। অ্যাপ্রোচ 2 বাস্তবায়ন সম্ভব নয়। যদি আমরা কোনও ( constexpr) আক্ষরিক অপারেটর ঘোষণা করতে পারি, তবে আমরা কীভাবে রিটার্নের ধরণটি নির্দিষ্ট করব? যেহেতু অক্ষরের একটি বৈচিত্র্যক্রমিক ক্রমটি ফেরত দেওয়ার জন্য আমাদের অপারেটরটির প্রয়োজন, তাই আমাদের রিটার্নের ধরণটি const char*নির্দিষ্ট করতে প্যারামিটারটি ব্যবহার করতে হবে:
constexpr auto
operator"" _s(const char* s, size_t n) -> /* Some metafunction using `s` */
এটি একটি সংকলন ত্রুটির ফলস্বরূপ, কারণ sএটি নয় constexpr। নিম্নলিখিতটি ব্যবহার করে এটিকে ঘিরে কাজ করার চেষ্টা করা খুব বেশি সহায়ক হয় না।
template <char... Ts>
constexpr sequence<Ts...> operator"" _s() { return {}; }
মান নির্দেশ করে যে এই নির্দিষ্ট আক্ষরিক অপারেটর ফর্মটি পূর্ণসংখ্যা এবং ভাসমান-পয়েন্ট ধরণের জন্য সংরক্ষিত। যদিও 123_sকাজ করবে, abc_sহবে না। যদি আমরা সম্পূর্ণরূপে ব্যবহারকারী-সংজ্ঞায়িত আক্ষরিক খাঁজ করি এবং কেবল একটি নিয়মিত constexprফাংশন ব্যবহার করি ?
template <unsigned Size>
constexpr auto
string(const char (&array)[Size]) -> /* Some metafunction using `array` */
আগের মতোই, আমরা এই সমস্যাটি নিয়ে চলেছি যে অ্যারে, এখন constexprফাংশনটির পরামিতি , নিজেই আর কোনও constexprধরণের নয়।
আমি বিশ্বাস করি যে একটি সি প্রিপ্রসেসর ম্যাক্রো সংজ্ঞায়িত করা সম্ভব হবে যা স্ট্রিং এবং স্ট্রিংয়ের BOOST_PP_FORআকারটিকে আর্গুমেন্ট হিসাবে গ্রহণ করে এবং স্ট্রিংয়ের অক্ষরগুলির সমন্বয়ে একটি ক্রম প্রদান করে ( স্ট্রিংকরণ, অ্যারে সাবস্ক্রিপ্ট এবং এর মতো)। তবে এ জাতীয় ম্যাক্রো প্রয়োগের জন্য আমার কাছে সময় (বা পর্যাপ্ত আগ্রহ) নেই =)
constexprফাংশনগুলির মধ্যে ব্যবহার করতে পারেন এবং অ্যারেগুলি (আরম্ভ করে, কনক্যাট, সাবস্ট্রাস্ট ইত্যাদি) শুরু করতে পারেন।
constexprস্ট্রিংগুলি বিশ্লেষণ করা যায়, যাতে আপনি ফলাফলের উপর নির্ভর করে বিভিন্ন কোড পাথ নিতে পারেন। মূলত, আপনি সি ++ এর মধ্যে ইডিএল তৈরি করতে পারেন; অ্যাপ্লিকেশনগুলি বেশ সীমাহীন।