القيم الثنائية مصنفة النوع المُعرّفة من المستخدم (Self-made user-defined literal for binary)
رغم إمكانية كتابة عدد ثنائي في C++ 14 على النحو التالي:
int number =0b0001'0101; // ==21
إلا أننا في الأسطر التالية سنستعرض مثالًا مشهورًا يوفّر طريقة أخرى ذاتية التنفيذ للأعداد الثنائية. لاحظ أن برنامج توسيع القالب التالي يعمل في وقت التصريف.
template < char FIRST, char...REST > struct binary { static_assert(FIRST == '0' || FIRST == '1', "invalid binary digit"); enum { value = ((FIRST - '0') << sizeof...(REST)) + binary < REST... > ::value }; }; template < > struct binary < '0' > { enum { value = 0 }; }; template < > struct binary < '1' > { enum { value = 1 }; }; // عامل قيمة خام مصنفة النوع template < char...LITERAL > inline constexpr unsigned int operator "" _b() { return binary < LITERAL... > ::value; } // عاملُ قيمةٍ خامٍ مصنَّفةِ النوع template < char...LITERAL > inline constexpr unsigned int operator "" _B() { return binary < LITERAL... > ::value; } #include <iostream> int main() { std::cout << 10101_B << ", " << 011011000111_b << '\n'; // تطبع 21, 1735 }
القيم مصنفة النوع المعيارية المُعرّفة من المستخدم (Standard user-defined literals for duration)
الإصدار ≥ C++ 14
فيما يلي قيمُ مدةٍ مصنَّفةِ النوع، ومعرَّفة من قِبل المستخدم (duration user literals)، مصرح عنها في فضاء الاسم namespace std::literals::chrono_literals
، حيث literals
و chrono_literals
هما فضاءا اسم ضمنيّان (inline namespaces). يمكن الوصول إلى هذه العوامل باستخدام using namespace std::literals
و using namespace std::chrono_literals
و using namespace std::literals::chrono_literals
.
#include <chrono> #include <iostream> int main() { using namespace std::literals::chrono_literals; std::chrono::nanoseconds t1 = 600ns; std::chrono::microseconds t2 = 42us; std::chrono::milliseconds t3 = 51ms; std::chrono::seconds t4 = 61s; std::chrono::minutes t5 = 88min; auto t6 = 2 * 0.5h; auto total = t1 + t2 + t3 + t4 + t5 + t6; std::cout.precision(13); std::cout << total.count() << " nanoseconds" << std::endl; // 8941051042600 nanoseconds std::cout << std::chrono::duration_cast < std::chrono::hours > (total).count() << " hours" << std::endl; // ساعتان }
القيم مصنَّفة النوع المُعرّفة من المستخدم، ذات قيَم long double
يوضّح المثال التالي كيفية استخدام قيم مصنَّفة النوع، مُعرّفة من المستخدم وذات قيَم long double:
#include <iostream> long double operator "" _km(long double val) { return val * 1000.0; } long double operator "" _mi(long double val) { return val * 1609.344; } int main() { std::cout << "3 km = " << 3.0_km << " m\n"; std::cout << "3 mi = " << 3.0_mi << " m\n"; return 0; }
خرج هذا البرنامج هو:
3 km = 3000 m 3 mi = 4828.03 m
السلاسل النصية المجردة القياسية والمعرّفة من المستخدم (Standard user-defined literals for strings)
الإصدار ≥ C++ 14
فيما يلي سلاسل نصية مجردةٌ ومُعرّفة من المستخدم (string user literals)، مُصرَّح عنها في namespace std::literals::string_literals
، حيث literals
و string_literals
هما فضاءا اسم مُضمّنان. ويمكن الوصول إلى هذه العوامل باستخدام using namespace std::literals
و using namespace std::string_literals
و using namespace std::literals::string_literals
.
#include <codecvt> #include <iostream> #include <locale> #include <string> int main() { using namespace std::literals::string_literals; std::string s = "hello world"s; std::u16string s16 = u"hello world"s; std::u32string s32 = U"hello world"s; std::wstring ws = L"hello world"s; std::cout << s << std::endl; std::wstring_convert < std::codecvt_utf8_utf16 < char16_t > , char16_t > utf16conv; std::cout << utf16conv.to_bytes(s16) << std::endl; std::wstring_convert < std::codecvt_utf8_utf16 < char32_t > , char32_t > utf32conv; std::cout << utf32conv.to_bytes(s32) << std::endl; std::wcout << ws << std::endl; }
ملاحظة: قد تحتوي السلاسل النصية المجردة على المحرف \0
، انظر المثال التالي:
// "foo"s النصية سينتج عنها C منشئات سلاسل std::string s1 = "foo\0\0bar"; // '\0' تحتوي هذه السلسلة النصية في وسطها على محرفين std::string s2 = "foo\0\0bar"s;
القيم مصنفة النوع المركّبة المعرّفة من المستخدم (Standard user-defined literals for complex)
الإصدار ≥ C++ 14
فيما يلي، قيم مركّبة مصنفة النوع ومعرّفة من المستخدم، مُصرًّح عنها فيnamespace std::literals::complex_literals
، حيث literals
و complex_literals
فضاءا اسم ضمنيان. يمكن الوصول إلى هذه العوامل باستخدام using namespace std::literals
و using namespace std::complex_literals
و using namespace std::literals::complex_literals
.
#include <complex> #include <iostream> int main() { using namespace std::literals::complex_literals; std::complex < double > c = 2.0 + 1i; // {2.0, 1.} std::complex < float > cf = 2.0f + 1if; // {2.0f, 1.f} std::complex < long double > cl = 2.0L + 1il; // {2.0L, 1.L} std::cout << "abs" << c << " = " << abs(c) << std::endl; // abs(2,1) = 2.23607 std::cout << "abs" << cf << " = " << abs(cf) << std::endl; // abs(2,1) = 2.23607 std::cout << "abs" << cl << " = " << abs(cl) << std::endl; // abs(2,1) = 2.23607 }
هذا الدرس جزء من سلسلة دروس عن C++.
ترجمة -بتصرّف- للفصل Chapter 114: User-Defined Literals من كتاب C++ Notes for Professionals
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.