رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران

پست های پیشنهاد شده

اگر شما توسعه دهنده سی‌پلاس‌پلاس هستید، توصیه می‌کنیم این سری از مقالات را دنبال کنید زیرا در این تاپیک قصد داریم به آخرین تغییرات مرتبط با سی‌پلاس‌پلاس مدرن اشاره کنیم. بنابراین در بخش اول، مهم‌ترین موارد منسوخ شده و اشکلات رفع شده و ویژگی‌های سی++ را پوشش خواهیم داد.

جزئیات C++ نسخه ۱۷ (بهبود‌ها و تغییرات)

بیایید به آرامی شروع کنیم، امروز ما به عناصر حذف شده و یا به موارد بهبود یافته‌ی کتابخانه استاندارد بپردازیم.

معرفی به صورت سلسله مراتبی

  • عناصر حذف شده و توسعه یافته (در این بحث)
  • شفاف سازی در زبان
  • قالب‌ها
  • ویژگی‌ها
  • تغییرات اول کتابخانه 
  • تغییرات دوم کتابخانه

مستندات و لینک‌ها

  1. قبل از هر چیز، اگر شما خودتان می‌خواهید استاندارد جدید را کاوش کنید آخرین پیش نویسه را در این بخش مطالعه کنید.
  2. در صورتی که می‌خواهید بدانید کدام کامپایلر از ویژگی‌های جدید پشتیبانی می‌کند، در این بخش آن را پیگیری کنید.
  3. تغییرات جدید از نسخه ویرایش سوم ۲۰۱۵ ویژوال استودیو در دسترس می‌باشند.
  4. علاوه بر این، لیستی از توصیف‌های مختصر از تمامی ویژگی‌های زبان سی‌پلاس‌پلاس ۱۷ تهیه شده است که در این بخش می‌توانید آن را ببینید که در قالب PDF از طرف مرجع رسمی می‌باشد.

مواردی که حذف شده اند
پیش نویس کنونی زبان حاوی ۱٬۵۸۶ صفحه است! با توجه به الزامات سازگاری، ویژگی‌های جدید اضافه شده اند، اما حذف نشده اند. خوشبختانه چیزهای وجود دارد که از بین خواهند رفت.

مواردی که ترجیح داده شده است که حذف شوند


حذف تریگراف
تریگراف‌ها کاراکترهای ویژه ترتیبی هستند که در موقع عدم پشتیبانی سیستم از نوع ۷ بیتی اَسکی (ASCII) همانند ایزو 646 استفاه شوند. برای مثال =?? کاراکتر ویژه‌ای مانند # تولید شده را در قالب -?? تولید می‌کند. تمامی مجموعه کاراکترهای اصلی سی‌پلاس‌پلاس در قالب 7 بیتی اسکی قرار دارند. موضوع فوق به ندرت مورد استفاده قرار می‌گیرد، بنابراین حذف آن ممکن است به ترجمه ساده کد کمک کند.

اگر شما می‌خواهید اطلاعات بیشتری در رابطه با کارآیی تیرگراف‌ها در سی++ کسب کنید به این لینک مراجعه کنید.

----------------------------------------------------------------------------
| trigraph | replacement | trigraph | replacement | trigraph | replacement |
----------------------------------------------------------------------------
| ??=      | #           | ??(      | [           | ??<      | {           |
| ??/      | \           | ??)      | ]           | ??>      | }           |
| ??’      | ˆ           | ??!      | |           | ??-      | ˜           |
----------------------------------------------------------------------------

شما جزئیات بیشتر را می‌توانید در N4086 بیابید.

اگر شما واقعا بهتری گراف‌ها در ویژوال استودیو نیاز دارید، نگاهی به مشخصه /Zc:trigraphs در بخش پیکربندی داشته باشید. همچنین، کامپایلرهای دیگر ممکن است مواردی را پشتیبانی نکنند. وضعیت انجام شده کنونی در کامپایلر های GCC:5.1 و Clang:3.5 می‌باشد.

حذف کلمه کلیدی register
کلمه کلیدی register در استاندارد 2011 سی‌پلاس‌پلاس منسوخ شده است و دیگر استفاده از آن معنایی ندارد. این کلمه کلیدی در حال حاضر حذف شده است. این کلمه کلیدی محفوظ است و ممکن است در نسخه های بعدی باز نویسی شود (مثلا autokeyword به عنوان یک چیز قدرتمند مجددا مورد استفاده قرار گرفته است).

جزئیات بیشتر در رابطه با این مورد در P0001R1 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلر‌های GCC 7.0 و Clang 3.8 انجام شده است.

حذف Operator++ bool
این اپراتور برای زمان بسیار زیادی است که منسوخ شده است! در سی پلاس پلاس ۹۸ تصمیم بر آن گرفته بودند که از آن استفاده کنند اما در نسخه ۱۷ سی‌پلاس‌پلاس کمیته موافقت خود را جهت حذف آن از زبان اعلام کرده است.

جزئیات بیشتر در رابطه با این مورد در P0002R1 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلر‌های GCC 7.0 و Clang 3.8 انجام شده است.

حذف مشخصات استثنایی از سی پلاس پلاس ۱۷
در سی پلاس پلاس ۱۷، مشخصات استثنایی بخشی از نوع سیستمی خواهند بود (به P0012R1 نگاه کنید). با این حال، استاندارد شامل مشخصات استثنایی قدیمی و منسوخ شده اند که به نظر غیرعلمی و غیرقابل استفاده است.

void fooThrowsInt(int a) throw(int) { 
  printf_s("can throw ints\n"); 
  if (a == 0) 
    throw 1; 
}

کد بالا در سی‌پلاس‌پلاس ۱۱ رد (منسوخ شده است). تنها اعلامیه استثنایی علمی throw() است، به این معنی است که این کد چیزی را در قالب throw انجام نخواهد داد. اما از سی‌پلاس‌پلاس ۱۱ به اینور، برنامه نویسان توصیه کرده اند که کسی از آن استفاده نکند.

برای مثال در کامپایلر Clang 4.0 شما باید خطای زیر را دریافت کنید:

error: ISO C++1z does not allow dynamic exception specifications [-Wdynamic-exception-spec]
note: use 'noexcept(false)' instead

جزئیات بیشتر در رابطه با این مورد در P0003R5 قابل مشاهده است. البته فعلا در MSVC انجام نشده است اما در کامپایلر‌های GCC 7.0 و Clang 3.8 انجام شده است.

حذف auto_ptr
این یکی از به روز رسانی‌های خوبی است که در سی‌پلاس‌پلاس ۱۱، ما اشاره گرهای هوشمند را دریافت کردیم : unique_ptr,shared_ptr و weak_ptr. با تشکر از این حرکتی که کمیته انجام داده بود، معنای واقعی این به روز رسانی در این بود که زبان می‌تواند پشتیبانی مناسبی از انتقال منابع منحصربفرد را داشته باشد. در این میان auto_ptr یک چیز قدیمی و نادرست در زبان بود به نا به دلایلی auto_ptr در این جا منسوخ شده است و باید به صورت خودکار به unique_ptr تبدیل شود.

توجه داشته باشیم که auto_ptr مدت کوتاهی است که از سی‌پلاس‌پلاس ۱۱ به اینور منسوخ شده است و بسیاری از کامپایلر ها منسوخ شدن آن را گزارش می‌دهند که به صورت زیر خواهد بود:

warning: 'template<class> class std::auto_ptr' is deprecated

در حال حاضر آن به وضعیت نامناسب تبدیل شده است، و اساساً کد شما کامپایل نخواهد شد. در اینجا خطا از طرف MSVC 2017 زمانی که از گزینه /std::c++latest استفاده کنید اعلام خواهد شد.

error C2039: 'auto_ptr': is not a member of 'std'

اگر شما نیاز به کمک از تبدیل از auto_ptr به unique_ptr دارید، می‌توانید Clang Tidy را بررسی کنید، زیرا آن عمل تبدیل خودکار را انجام خواهد داد. اطلاعات بیشتر در سند N4190 موجود است.

همچنین موارد مرتبط دیگری با سند N4190 وجود دارند که در کتابخانه خذف شده اند مانند:

  • unary_function/binary_function
  • ptr_fun()
  • mem_fun()/mem_fun_ref()
  • bind1st()/bind2nd()
  • random_shuffle

قوانین جدید خودکار برای Direct-List-Initialization از سی پلاس پلاس ۱۱ به اینور که ما یک مشکل بزرگی در این رابطه داشتیم:

auto x { 1 };

از initializer_list اینطور نتیجه‌گیری شده است. با استاندارد جدید، ما می‌توانیم این مشکل را حل کنیم. بنابراین آن می‌تواند به عنوان نوع int که اکثر مردم تصور می‌کنند شناسایی شود. برای اینکه این اتفاق بیافتد، ما نیاز داریم که دو روش تخصیص مقدار اولیه را درک کنیم: کپی و مستقیم.

  • auto x = foo(); // copy-initialization
  • auto x{foo}; // direct-initialization, initializes an
  • // initializer_list (until C++17)
  • int x = foo(); // copy-initialization
  • int x{foo}; // direct-initialization

برای مقدار دهی اولیه، سی‌پلاس‌پلاس ۱۷ قوانین جدیدی را معرفی می‌کند:

  • For a braced-init-list with only a single element, auto
  • deduction will deduce from that entry;
  • For a braced-init-list with more than one element, auto
  • deduction will be ill-formed.

برای مثال:

auto x1 = { 1, 2 };   // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
auto x3{ 1, 2 };      // error: not a single element
auto x4 = { 3 };      // decltype(x4) is std::initializer_list<int>
auto x5{ 3 };         // decltype(x5) is int

جزئیات بیشتر را در سند N3922 می‌توانید مشاهده کنید. همچنین جزئیات در رابطه با فهرست خودکار موجود هستند که توسط جناب آقای Ville Voutilainen اشاره شده است. این اضافات در سی‌پلاس‌پلاس از زمان MSVC 14.0، GCC 5.0 و Clang 3.8 کار می‌کنند.

گزینه static_assert بدون هیچ نوع پیغامی
این واضح است که، این به شما این امکان را می دهد که فقط بدون داشتن گذراندن پیام، نسخه دارای پیغام در دسترس خواهد بود. این سازگاری با سایر موارد مانند BOOST_STATIC_ASSERT وجود دارد.

static_assert(std::is_arithmetic_v<T>, "T must be arithmetic");
static_assert(std::is_arithmetic_v<T>); // no message needed since C++17

جزئیات بیشتر در سند N3928 در دسترس است. پشتیبانی شده در MSVC 2017 ٬ GCC 6.0 و Clang 2.5.

انواع مختلف شروع و پایان در محدوده حلقه
از سی‌پلاس‌پلاس ۱۱ به بعد، محدوده مبتنی بر حلقه ها به صورت داخلی تعریف شده است:

{
auto && __range = for-range-initializer;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
  for-range-declaration = *__begin;
  statement
}
}

همانطور که می‌بینید، __begin و __end دارای نوع مشابه هستند. این ممکن است باعث مشکلاتی شود. برای مثال زمانی که شما چیزی شبیه یک نگهبان (محافظ) که از نوع داده دیگری است را داشته باشید مشکل ساز خواهد بود.

در سی‌پلاس‌پلاس ۱۷ آن به صورت زیر تغییر کرده است:

{
auto && __range = for-range-initializer;
auto __begin = begin-expr;
auto __end = end-expr;
for ( ; __begin != __end; ++__begin ) {
  for-range-declaration = *__begin;
  statement
}
}

انواع __begin و __end ممکن است متفاوت باشد چرا که فقط اپراتور مقایسه مورد نیاز است. این تغییر کلی باعث می‌شود که این ویژگی تجربه بیشتری را در این زمینه برای کاربران ارائه دهند. جزئیات بیشتر در P0184R0، پشتیبانی شده در MSVC 2017 ،GCC 6.0 و Clang 3.6.

  • پسندیدن 1
  • تشکر شده 2

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
مهمان
این موضوع برای عدم ارسال قفل گردیده است.

  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

×
×
  • جدید...