C ++ में संकलन-समय के दौरान स्ट्रिंग्स बनाने और हेरफेर करने में सक्षम होने के कारण कई उपयोगी एप्लिकेशन हैं। यद्यपि C ++ में संकलन-समय स्ट्रिंग्स को बनाना संभव है, प्रक्रिया बहुत बोझिल है, क्योंकि स्ट्रिंग को वर्णों के एक वैचारिक अनुक्रम के रूप में घोषित किया जाना चाहिए, जैसे
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
स्ट्रिंग्स को संकलन-समय के दौरान पार्स किया जा सकता है, ताकि आप परिणामों के आधार पर विभिन्न कोड पथ ले सकें। अनिवार्य रूप से, आप C ++ के भीतर EDL बना सकते हैं; अनुप्रयोग बहुत असीम हैं।