همان ساختارهای داده‌ای هستند که برای ذخیره‌سازی مجموعه‌ای از اشیاء از یک نوع خاص طراحی شده‌اند. این کانتینرها به چند دسته‌ی اصلی تقسیم می‌شوند: کانتینرهای ترتیبی (Sequence Containers) مانند vector، list و deque که ترتیب عناصر را حفظ می‌کنند، کانتینرهای مرتب‌شده (Associative Containers) مانند set و map که عناصر را بر اساس کلید مرتب می‌کنند، و کانتینرهای نامرتب (Unordered Associative Containers) که از جدول درهم‌سازی برای دسترسی سریع استفاده می‌کنند .

الزامات کلی کانتینرها

تمام کانتینرهای تعریف‌شده در استاندارد، باید مجموعه‌ای از الزامات را برآورده سازند. یکی از مهم‌ترین این الزامات، نحوه‌ی تأمین حافظه است. بر اساس مستندات استاندارد، تمام کانتینرهای تعریف‌شده در این بخش، حافظه‌ی خود را از طریق یک تخصیص‌دهنده (Allocator) دریافت می‌کنند . کانتینرها و تکرارگرهای آنها، اشاره‌گرهایی به عناصر تخصیص‌یافته را از طریق نوع اشاره‌گر تخصیص‌دهنده ذخیره می‌کنند .

همچنین برای نوع عناصر کانتینرها، از C++17 به بعد، کانتینر (اما نه اعضای آن) را می‌توان با یک نوع ناقص (Incomplete Type) نمونه‌سازی کرد، به شرطی که تخصیص‌دهنده، الزامات کامل‌بودن نوع را برآورده سازد .

توابع کمکی غیرعضوی در C++17

C++17 سه تابع کمکی غیرعضوی مهم را به کتابخانه‌ی استاندارد اضافه کرده است که یک رابط یکپارچه برای کار با کانتینرها، آرایه‌های ساده و std::initializer_list فراهم می‌کنند . این توابع عبارتند از:

std::size

این تابع، اندازه‌ی یک کانتینر یا آرایه را بازمی‌گرداند. برای کانتینرهای استاندارد، متد size() عضو را فراخوانی می‌کند و برای آرایه‌ها، مستقیماً تعداد عناصر را محاسبه می‌کند . این تابع یک روش یکسان برای دریافت اندازه، صرف‌نظر از نوع داده‌ی ورودی، ارائه می‌دهد.

std::empty

تابع std::empty بررسی می‌کند که آیا یک کانتینر یا آرایه خالی است یا خیر. خروجی این تابع یک مقدار بولین است که در صورت خالی بودن، true و در غیر این صورت، false بازمی‌گرداند .

std::data

این تابع، یک اشاره‌گر به داده‌های زیرین یک کانتینر یا آرایه بازمی‌گرداند. برای کانتینرهایی که متد data() را ارائه می‌دهند (مانند vector و string)، نتیجه‌ی آن متد بازگردانده می‌شود و برای آرایه‌ها، اشاره‌گر به اولین عنصر آرایه برگردانده می‌شود . نکته‌ی مهم این است که std::data برای std::string نیز به‌درستی کار می‌کند و در C++17، نسخه‌ی قابل‌تغییر (mutable overload) آن نیز پشتیبانی می‌شود .

قابلیت استخراج گره (Node Extraction) در C++17

یکی از قابلیت‌های مهم C++17 برای کانتینرهای مرتب‌شده و نامرتب، متد extract است. این متد، یک گره (Node) را از کانتینر جدا کرده و آن را به‌صورت یک دسته‌ی گره (Node Handle) برمی‌گرداند، بدون اینکه عنصر کپی یا جابه‌جا شود . این قابلیت دو شکل اصلی دارد: یکی برای استخراج بر اساس موقعیت (iterator) و دیگری برای استخراج بر اساس کلید .

مهم‌ترین کاربرد extract، تغییر کلید یک عنصر در کانتینرهای map یا set بدون نیاز به تخصیص مجدد حافظه است. به‌عنوان مثال، می‌توان یک گره را با کلید مشخص استخراج کرد، کلید آن را تغییر داد و سپس آن را به کانتینر بازگرداند . این عملیات، بسیار کارآمدتر از روش‌های قدیمی مانند حذف و درج مجدد است .

جمع‌بندی

C++17 با افزودن توابع کمکی مانند std::size، std::empty و std::data، کار با کانتینرهای مختلف را یکدست‌تر و ساده‌تر کرده است. همچنین قابلیت extract و مفهوم دسته‌های گره، عملیات روی کانتینرهای مرتب‌شده را به‌طور چشمگیری بهینه‌سازی کرده است. علاوه بر این، انعطاف‌پذیری بیشتر در استفاده از انواع ناقص به‌عنوان عناصر کانتینر، مرزهای استفاده از این ساختارهای داده‌ی قدرتمند را گسترش داده است.

کلیدواژه ها : std::size-std::empty-std::data-C++17 container helpers-توابع کمکی کانتینر در C++17-extract in C++17-node handle C++17-استخراج گره در C++17-کانتینرهای STL-الزامات کانتینر در C++17-incomplete type container C++17-آموزش کانتینرهای C++17-مشخصات کانتینرهای STL-توابع غیرعضوی C++17