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

قابلیت‌های ممتاز ++C در نسخه‌های ۱۱ و ۱۴ و ۱۷

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

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

جزئیات 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

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


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

جزئیات در ++C ویرایش ۱۷: کد نویسی ساده

با توجه به مشخصاتی که در سی‌پلاس‌پلاس ۱۷ که ارائه شده است، ویژگی‌های جدید برای این معرفی می‌شوند تا کد شما تمیز تر و بهتر اعمال شوند. این مقاله را برای مطلع شدن از جزئیات بیشتر بخوانید. با هر استاندارد سی‌‌‌پلاس‌‌پلاس که ارائه می‌شود، هدف از آن تولید کد ساده تر، واضح تر و رسا تر می‌باشد. سی‌پلاس‌پلاس ۱۷ چندین ویژگی بزرگ زبان را ارائه می‌دهد که باعث می‌شود کد ما زیباتر و بهتر شود. بنابراین بیایید باهم یک نگاهی به این ویژگی‌ها داشته باشیم.

ممکن است شما بگویید که بیشترین ویژگی‌های جدید زبان (به جز پیشرفت های کتابخانه استاندارد - STL) برای نوشتن کد ساده تر و پاکتر می‌باشند. با توجه به مجموعه جزئیات سی‌پلاس‌پلاس ۱۷ که بسیاری از چیزهای بزرگ را مورد بررسی قرار داده است، ما امروز تنها برای بعضی از ویژگی ها که از داخل این مجموعه عظیم بیرون کشیده‌ایم اشاره خواهیم داشت که باعث می‌شود کد شما فشرده‌تر و بهینه تر شود.

  • پیوند‌های ساخت یافته / اعلان‌های تجزیه
  • عبارت Init-statement برای if/switch
  • متغیرهای درون خطی (inline)
  • شرط constexpr if
  • و چند موارد دیگر

پیوند‌های ساخت یافته، آیا اغلب با tuple ها کار کرده‌اید؟

اگر نه، پس احتمالاً باید به آن نگاهی کنید. tuple ها تنها برای بازگشت مقادیر چند گانه از یک تابع پیشنهاد نمی‌شوند، آنها پشتیبانی ویژگی‌ای از زبان را داشتند. به طوری که باعث می‌شود کد ساده تر و پاکتر شود.

برای مثال (std::tie که از مرجع اصلی سی‌پلاس‌پلاس به دست آمده است) به صورت زیر است:

std::set<S> mySet; 
S value{42, "Test", 3.14}; 
std::set<S>::iterator iter; 
bool inserted; // unpacks the return val of insert into iter and inserted 
std::tie(iter, inserted) = mySet.insert(value); 
if (inserted) 
std::cout << "Value was inserted\n";

توجه داشته باشید که باید iter و inserted را ابتدا وارد کرده باشید. سپس شما می‌‌توانید از std::tie استفاده کنید. با این حال این بخش کوچکی از کد نمونه است:

std::set<S> mySet; 
S value{42, "Test", 3.14}; 
auto [iter, inserted] = mySet.insert(value);

اینجا توجه داشته باشید که یک خط به جای سه خط جایگزین شده است! این کد ساده‌تر و خوانا‌تر و درعین حال ایمن‌ تر است، اینطور نیست؟ همچنین، شما هم اکنون می‌‌توانید از const استفاده کنید و آن را به صورت const auto [iter inserted] بنویسید که صحیح است.

پیوند ساختاری تنها به tuple ها ختم نمی‌شود، چرا که ما سه مورد دیگر را داریم:

  • اگر مقدار دهی اولیه یک آرایه باشد:
// works with arrays: 
double myArray[3] = { 1.0, 2.0, 3.0 }; 
auto [a, b, c] = myArray;
  • اگر مقدار دهی اولیه std::tuple_size<> را پشتیبانی کند و تابع get را فراهم کند که شایع ترین مورد است.
auto [a, b] = myPair; // binds myPair.first/second

به عبارت دیگر، شما می‌‌توانید کلاس‌های خود را پشتیبانی کنید، با فرض این که شما تابع get را در پیاده سازی رابط کلاس خود اضافه کرده باشید.

  • اگر مقدار دهی اولیه فقط شامل اعضای عمومی شود در این صورت:
struct S { 
 int x1 : 2; 
 volatile double y1; 
}; 
S f(); 
const auto [ x, y ] = f();

در حال حاضر این روش برای دریافت یک مرجع از یک عضو tuple آسان است.

auto& [ refA, refB, refC, refD ] = myTuple;

و یکی از جالب‌ترین استفاده‌‌ها (پشتیبانی از حلقه‌ها است):

  std::map myMap; 
  for (const auto & [k,v] : myMap) 
  { // k - key 
   // v - value 
  }

پیوند ساختاری یا تقسیم بندی اعلان‌ها
برای این ویژگی، ممکن است شما نام های دیگری را دیده باشید، "اعلان تجزیه". همانطور که می‌‌بینیم، این دو نام در نظر گرفته شده است، اما فعلاً استاندارد سازی در حالت پیش‌نویسه است و با نام "پیوند‌های ساختاری" می‌‌باشند.

جزئیات بیشتر در رابطه با این مورد در اسناد P0217R3، P0144R0 و P0615R0 موجود هستند. همچنین این مورد با کامپایلر‌‌های GCC 7.0،MSVC2017 و Clang 4.0 سازگار است.

عبارت Init-statement برای if/switch
نسخه جدید عبارت شرطی if و switch در سی‌پلاس‌پلاس جدید به صورت زیر است:

if (init; condition) , switch (init; condition)

قبلاً باید به صورت زیر می‌نوشتیم:

{ 
 auto val = GetValue(); 
 if (condition(val)) 
 // on success 
 else 
 // on false... 
}

در اینجا val یک دامنه جدا کننده بدون دارد که باعث "نشت - فقدان" در خاتمه دهنده دامنه خواهد شد. در حالی که شما در نسخه جدید می‌‌‌توانید به صورت زیر بنویسید:

if (auto val = GetValue(); condition(val)) 
  // on success 
 else 
  // on false...

متغیر val تنها در داخل عبارات if و else قابل رویت است، بنابراین آن یک "نَشت" نخواهد داشت. condition ممکن است چندین عبارت باشد نه تنها if بنابراین متغیر val یکی از دو مقدار true/false را خواهد داشت.

چرا این ویژگی کاربرد دارد؟
اجازه دهید تا به شما بگوییم زمانی که می‌خواهید چندین چیز را در یک رشته را جستجو کنید به صورت زیر خواهید داشت:

const std::string myString = "My Hello World Wow"; 
const auto it = myString.find("Hello"); 
if (it != std::string::npos) 
 std::cout << it << " Hello\n" 
const auto it2 = myString.find("World"); 
if (it2 != std::string::npos) 
 std::cout << it2 << " World\n"

ما باید از نام‌‌های مختلفی برای it استفاده کنیم و یا اینکه آن را با دامنه خاتمه دهنده جدا سازیم.

{ 
 const auto it = myString.find("Hello"); 
 if (it != std::string::npos) 
 std::cout << it << " Hello\n" 
} 
{ 
 const auto it = myString.find("World"); 
 if (it != std::string::npos) 
 std::cout << it << " World\n" 
}

عبارت جدید شرطی if در نسخه جدید یک دامنه اضافه را در یک خط ایجاد می‌‌کند.

if (const auto it = myString.find("Hello"); it != std::string::npos) 
 std::cout << it << " Hello\n"; 
if (const auto it = myString.find("World"); it != std::string::npos) 
 std::cout << it << " World\n";

همانطور که قبلاً اشاره شده است، متغیر تعریف شده در عبارت شرطی if در بلوک دیگری قابل مشاهده است. بنابراین شما می‌‌تواین به صورت زیر بنویسید:

if (const auto it = myString.find("World"); it != std::string::npos) 
 std::cout << it << " World\n"; 
else 
 std::cout << it << " not found!!\n";

به علاوه، شما می‌‌توانید آن را با پیوند ساختاری بر اساس کد نمونه از جانب (Herb Sutter) استفاده کنید:

// better together: structured bindings + if initializer 
if (auto [iter, succeeded] = mymap.insert(value); succeeded) { 
 use(iter); // ok 
 // ... 
} // iter and succeeded are destroyed here

جزئیات بیشتر در اسناد زیر آمده است:

متغیرهای درون خطی (inline)
با شروع مقدار دهی داده‌های غیر استاتیک، اکنون می‌‌توانیم یک متغیر عضو را دی یک مکان اعلام کنیم. با این حال، با متغیر‌های استاتیک یا const static، معمولاً باید آن را در برخی از فایل‌های cpp تعریف کنید. در سی‌پلاس‌پلاس ۱۱ و کلید واژه constexpr که مارا قادر می‌سازد تا در یک مکان اعلان و تعریف متغیر‌های استاتیک را انجام دهیم، اما این امکان تنها به constexpr محدود می‌‌شود.

قبلاً فقط روشها/توابع می‌‌توانستند به عنوان inline تعریف شوند، حالا شما می‌‌توانید این کار را با متغیر ها در داخل فایل هدر انجام دهید. یک متغیر اعلام شده درون خطی معنای مشاهبی دارد بنابراین همانند یک تابع inline تعریف می‌‌شود. آن را می‌‌توان به واحد‌های ترجمه چند گانه نیز تعریف کرد. مثال‌‌های زیر را ببینید:

struct MyClass { 
 static const int sValue; 
}; 
inline int const MyClass::sValue = 777;

و حتی

struct MyClass { 
 inline static const int sValue = 777; 
};

همچنین توجه داشته باشید که متغیر‌های constexpr به طور ضمنی inline هستند، بنابراین نیازی به استفاده به صورت constepr inline myVar = 10; نمی‌‌باشد.

این ویژگی چرا کد را ساده تر می‌‌کند؟

برای مثال، تعداد زیادی از هدرها در کتابخانه تنها تعدادی از روش های (هک‌) را محدود می‌‌کنند (مانند استفاده توابع درون خطیinline و یا قالب ها) و در نهایت مزیت constexpr این است که مقدار دهی اولیه شما نباید constexpr باشد.

جزئیات بیشتر در رابطه با این ویژگی در سند زیر موجود است:

این مورد با کامپایلر‌های GCC 7.0 و Clang 3.9 سازگار است اما فعلاً با MSVC سازگاری ندارد.

ویژگی مربوط به constexpr if
ممکن است در بعضی جاها به قابلیت std::enable_if در سی‌پلاس‌پلاس ۱۴ نگاه کنید که آن به راحتی با constexpr if جایگزین می‌شود.

بنابراین، در اکثر موارد، ما اکنون می‌‌توانیم تنها با نوشتن عبارت یک constexpr if این کار را بهتر و تمیز تر انجام دهیم. این ویژگی برای برنامه نویسی metaprogramming/template بسیار مهم است که احتمالاً طبیعت آن بسیار پیچیده خواهد بود.

یک مثال ساده با تابع Fibonacci:

template<int N> 
constexpr int fibonacci() {
 return fibonacci<N-1>() + fibonacci<N-2>(); 
} 
template<>
constexpr int fibonacci<1>() { 
 return 1; 
} 
template<> 
constexpr int fibonacci<0>() { 
 return 0; 
}

حال می‌‌توان آن را تقریباً در یک حالت نرمال (نسخه بدون کامپایل) نوشت:

template<int N> 
constexpr int fibonacci() { 
 if constexpr (N>=2) 
 return fibonacci<N-1>() + fibonacci<N-2>(); 
 else 
 return N; 
}

در رویداد ۱۸ هم جلسات هفتگی سی‌پلاس‌پلاس در جیسون ترنر نمونه‌‌ای را می‌‌توان یافت که در آن عبارت constexpr if هیچ منطق اتصال کوتاهی را در زمان کامپایل انجام نمی‌‌‌دهد، بنابراین این کد باید کامپایل شود:

if constexpr (std::is_integral<T>::value && 
 std::numeric_limits<T>::min() < 10)
{ 
}

در کد فوق برای T شما در std::strin‌g خطایی کامپایل را دریافت خواهید کرد زیرا numeric_limits برای رشته ها تعریف نشده اند.

در جلسات C++NOW 2017 آقای Bryce Leblbach با عنوان جلسه خود C++17 Features در ۱۶ دقیقه مثال بسیار زیبایی را در رابطه باconstexpr if زد که می‌‌تواند برای تابع get استفاده شود که آن برای پیوند ساختاری مورد استفاده قرار می‌‌گیرد.

struct S { 
 int n; 
 std::string s;
 float d; 
}; 
template <std::size_t I> 
auto& get(S& s) { 
 if constexpr (I == 0) 
 return s.n; 
 else if constexpr (I == 1) 
 return s.s; 
 else if constexpr (I == 2) 
 return s.d; 
}

قبلاً ما باید به صورت زیر می‌‌نوشتیم:

template <> 
 auto& get<0>(S &s) { 
  return s.n; 
 } 
 template <> 
 auto& get<1>(S &s) { 
  return s.s; 
 } 
 template <> 
 auto& get<2>(S &s) { 
  return s.d;
 }

همانطور که می‌‌بینید، مشکل سوال برانگیز اینجاست که کد در این جا ساده تر است. اگر چه در این مورد فقط از یک ساختار ساده استفاده شده است، با برخی از نمونه های واقعی دنیا، کد نهایی باید بسیار پیچیده تر از این باشد بنابراین باید constexpr if کد تمیز تری نسبت به این مورد باشد.

این مورد با کامپایلر‌های GCC 7.0،MSVC-2017.3 و Clang 3.9 سازگار است.

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

  • قالب‌ (template)
  • عبارت Fold
  • الگو برای کلاس ها 

بنابراین برای ذکر ویژگی‌‌های بیشتر در رابطه با نسخه جدید در پستهای آن ها را پوشش خواهیم داد. شک نکنید که، سی‌پلاس‌پلاس ۱۷ پیشرفت واقعی را در برابر کد های جمع و جور و آسان فراهم گرده است. یکی از بهترین چیزها constexpr است که آن به ما اجازه می‌دهد کد template/metaprogramming را به روش کد استاندارد شده بنویسیم. این یک مزیت بسیار بزرگی است.

ویژگی دوم: پیوند ساخت یافته (که حتی برای حلقه ها کار می‌‌کند) مانند حسی را القا می‌‌کند که در زبان‌های پویایی مثل Python وجود دارد.

همانطور که می‌‌بینید، تمام ویژگی‌های ذکر شده در حال حاضر در Clang، MSVC و GCC  قابل اجرا هستند. اگر شما با نسخه های اخیر این کامپایلر ها کار می‌کنید می‌تواین بلافاصله با سی‌++ ۱۷ کار کرده و آن را تجربه کنید.

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

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


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

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

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

  • مطالب مشابه

    • توسط کامبیز اسدزاده
      آیا این واقعاً امکان‌پذیر است؟
      پاسخ :  بله!
      من می‌دانم که ممکن است این مبحث تحت سی++ بسیار پیچیده و یک کار بیهوده‌ای باشد! اما واقعیت مساله این است که تا چیزی رو خودتون ندیدین و انجامش ندادین با حرف و حدیث بقیه باورش نکنید!
      من قبلاً در مورد اینکه تحت ++C وب‌سایت میشه طراحی کرد یا خیر تحقیقاتی انجام داده بودم، از لحاظ امکان بودنش جواب مثبت بود اما اینکه به راحتی طراحی تحت Php یا دیگر زبان‌های برنامه‌نویسی باشه خیر! خُب طبیعیه چون شما بسیار راحت یه اسکریپت رو می‌نویسی و روی سرور اجراش می‌کنی و سایت شما به خوبی و خوشی بالا میاد!
      ممکن است در همین قسمت از موضوع شما به این نتیجه رسیده باشید که خُب نیازی به ادامه‌ی بحث نداریم! وقتی کار سختیه پس منطقی نیست و شما احتمالاً دیوانه‌ای!!! 😁
      واقعیت جریان این است بر خلاف آن چیزی که تصور کرده‌ایم طراحی وب‌سایت با سی‌پلاس‌پلاس نه تنها بسیار راحت است بلکه بسیار هم جذاب خواهد بود! اما در نگاه اول ممکن است یک سری محدودیت‌هارا داشته باشد که همه‌ی این موارد با کمی تعمل و بررسی قابل حل هستند به قدری که وقتی درگیر این جریان باشید شیفته‌ی آن خواهید شد.
       
      مزایای یک وب‌سایت تحت سی‌پلاس‌پلاس نسبت به دیگر زبان‌های رایج
      سرعت خارق‌العاده و غیر قابل مقایسه با زبان‌های رایج امنیت بهتر کد‌های شما مدیریت ساده‌تر و انعطاف‌پذیری بالا مصرف بسیار بهینه‌ و غیر قابل تصور از منابع سرور دسترسی نامحدود به کتابخانه‌ها عدم محدودیت در دسترسی به برنامه‌نویسی سطح پایین عدم محدودیت در استفاده از توابع سیستم‌عامل عدم محدودیت در مدیریت سیستم و هر ویژگی‌ دیگری که در زبان‌های اسکریپتی اگر به آن نیاز داشته باشید مجبور هستید تا به صورت اکستنشن آن را تحت سی‌پلاس‌پلاس باز نویسی کنید. سیستم راه‌انداز وب‌سرور چگونه است؟
      در هر سروری CGI به شما امکان این را می‌دهد که بتوانید تحت پروتکل‌های استاندارد برنامه‌های تحت وب را اجرا کنید. شما می‌توانید تحت آن و یا موارد دیگری مانند FatCGI و WSGI و دیگر موارد بهینه شده‌ی آن برنامه‌ی تحت وب را بر روی سرور خود اجرا کنید.
       
      طراحی قالب هماهنگی با HTML, JavaScript, Css در سی‌پلاس‌پلاس چگونه خواهد بود؟
      همه‌ی گزینه‌های مربوط به وب را شما بدون هیچ محدودیتی در اختیار خواهید داشت. شما هیچ محدودیتی در استفاده از ویژگی‌های HTML5 یا CSS3 و یا JavaScript و دیگر فریمورک‌ها و کتابخانه‌های کارآمدی چون Angular.JS را نخواهید داشت. بنابراین از نظر طراحی رابط یک وب‌سایت همانند دیگر زبان‌های رایج می‌توانید روی آن حساب کنید.
       
      طراحی هسته و بک‌اِند وب‌سایت چگونه خواهد بود؟
      همانند زبان‌ها و فریمورک‌های رایج تحت وب شما در سی‌پلاس‌پلاس می‌توانید هسته‌ی وب‌سایت یا سیستم وب‌سایت خود را تحت استاندارد سی‌پلاس‌پلاس و هر کتابخانه‌ای که می‌پسندید و یا به آن تسلط دارید پیاده سازی کنید! به شرطی که قابلیت‌های آن کتابخانه پاسخگوی نیاز‌های شما باشد.
      با این حساب شما می‌توانید حتی سیستم مدیریت محتوای (CMS) خود را طراحی کنید! 😧
      بله سیستم مدیریت محتوا تحت سی‌پلاس‌پلاس! کاملاً جدی هستیم 🙂
      قبل از هر چیز یک مزیت بسیار بزرگی که یک CMS تحت سی‌پلاس‌پلاس می‌تواند داشته باشد مصرف بهینه از منابع سرور خواهد بود. برای مثال در یک مقایسه‌ی‌ ساده و آزمایشی نتیجه‌ی بسیار جالبی ارائه شده است.
      همانطور که می‌دانید Wordpress به عنوان یک سیستم مدیریت محتوای (بلاگ) شناخته شده و تحت Php توسعه‌ یافته است. نسخه‌ی سریعتر و بهینه‌تر آن با نام Ghost تحت Node.JS توسعه یافته است که ما نسخه‌ی توسعه‌ یافته‌ی آن را با یک عمل مشابه در C++1z مورد بررسی قرار داده ایم که نتایج آن بسیار جالب است!
      مصرف حافظه‌
      سیستم مدیریت محتوای Jaguar ۳۵۰۰ درخواست در هر ثانیه 3.6 مگابایت سیستم مدیریت محتوای Ghost 100 درخواست در ثانیه 120 مگابایت پشتیبانی از پایگاه‌های داده
      به لطف کتابخانه‌های عظیم سی‌پلاس‌پلاس امکان مدیریت یک وب‌سایت تحت پایگاه‌های داده مختلفی ممکن است. برای مثال تحت Qt شما می‌توانید به رایجترین درایور‌های بانک‌اطلاعاتی دسترسی داشته و سیستم خود را به آن‌ها مجهز کنید.
      نکته: احتمالاً در برنامه‌نویسی با نود جی‌اس و پی‌اچ‌پی شناختی با کتابخانه‌های OpenSSL, Libcurl و موارد این چنینی داشته اید! کتابخانه‌های فوق عضو لیست کتابخانه‌های C و  ++C هستند. بنابراین شما علاوه بر دسترسی مستقیم بر آن‌ها به هزاران و شاید میلیون‌ها کتابخانه در دنیا سی‌پلاس‌پلاس خواهید داشت.
       
      نمونه‌ی اولیه اما شوق‌آور برای اثبات امکان طراحی وب‌سایت تحت سی‌پلاس‌پلاس
      چندی پیش من تصمیم گرفتم تا سیستم وب‌سایتی را تحت Php7 برای یکی از استارت‌آپ‌ها طراحی و پیاده سازی کنم که در این پست به آن اشاره شده است. از آن‌جایی که به لطف کتابخانه‌ی Qt برنامه‌های سمت کاربر را توسط سی‌پلاس‌پلاس پیاده سازی کرده بودم به این فکر افتادم چرا سمت سرور و بخش وب‌سایت هم با آن هماهنگ نشود!؟
      اینگونه هماهنگی بین برنامه‌ها و پرفرمنس همه‌ی آن‌ها بسیار افزایش خواهد یافت در اولین نگاه این تفکر بسیار ناشیانه و بسیار ناممکن بود! تنها روشی که به کار گرفته بودم ارسال اطلاعات از طرف کاربر به سمت سرور و مدیریت آن‌ها تحت معماری Restful Api بود که در قالب JSon آن‌ها را تجزیه و مدیریت می‌کردم. با کمی تحقیق در مورد ویژگی‌های سمت وب  تحت Fast-CGI, uWSGI, DJango, ClearSilver و موارد مرتبط با آن‌ها سعی کردم تا صفحه‌ی بسیار ساده‌ای از HTML را توسط سی‌پلاس‌پلاس هندل کنم. این کار نتایج بسیار موفقیت آمیزی را در بر داشت تا نتیجه‌ی آن تبدیل به یک پروژه‌ی سیستم مدیریت محتوا تحت ++C شد.
      من پروژه‌ای با نام مفهومی Jaguar که نام پروژه‌ی قبلی تحت Php بود را در محیط Qt Creator با C++17 و کتابخانه‌ی Qt باز سازی کرده و هسته‌ی اولیه‌ی آن را برای اجرای چند صفحه از یک وب‌سایت، احراز حویت، بازخوانی و نمایش لیستی از خبر‌ها و مدیریت متا تگ‌ها و آدرس صفحات مربوط به هر صفحه را ایجاد کردم.
      سعی کرده ام در کمترین زمان ممکن برای آزمایش یک سری ویژگی‌های اولیه از یک وب‌سایت آن‌ها را مورد بررسی قرار بدم که عبارتند از هماهنگی با فریم‌ورک‌های طراحی مانند BootStrap و یا Angular.JS که خوشبختانه همه‌چیز بسیار خوب در کنار همدیگه کار می‌کنند. هسته‌ی سیستم به صورت جدا و معماری طراحی آن بر پایه‌ی MVC مورد آزمایش قرار گرفته است.
      در زیر تصاویری از صفحات تولید شده تحت سیستم‌ مدیریت محتوای ساخته شده با سی‌پلاس‌پلاس را مشاهده می‌کنید. 😉







      همه چیز در قدم‌های اول قرار دارد و با توجه به سادگی تولید وب سایت بر خلاف تصوری که داشتیم بسیار توسعه و جای پیشرفت خواهد داشت. بخشی از نمونه کد‌های این سیستم به صورت زیر آورده شده است تا ذهنیتی برای توسعه‌دهندگان ارائه شود:
      تکه کُد زیر عمل ارسال اطلاعات و تمامی لینک‌های مربوط به بوت استرپ را برای سمت HTML ارائه می‌کند که در قالب استاندارد جدید C++17 آورده شده است:
      auto bootstrapCss = bootStrapLib.find("css"); if(bootstrapCss != bootStrapLib.end()) { c->setStash("BootstrapCss", bootstrapCss->second.c_str()); std::cout << "Found " << bootstrapCss->first << " " << bootstrapCss->second << '\n'; } کد مربوط به سمت قالب به صورت زیر خواهد بود:
      <!-- Bootstrap core css --> <link href="{{BootstrapCss}}" rel="stylesheet"> نتیجه‌ی فوق در صورتی که CDN بر روی لوکال تنظیم شده باشد از روی کد‌های کامپایل شده و یا استاتیک فراخوانی خواهد شد. در غیر اینصورت از روی یکی از سرور‌های CDN فراخوانی می‌شوند.
      نحوه‌ی ارسال متغیر از سمت سی‌پلاس‌پلاس به قالب بسیار ساده است! بسیار ساده از Php و یا Node.JS می‌باشد. با در نظر گرفتن ارسال اطلاعات از سمت سی‌پلاس‌پلاس به سمت رابط کاربری کافی است نام متغیر‌ها را در قالب خود اعمال کنید.
      {% for post in news %} <div class="blog-post"> <h2 class="blog-post-title"><a href="news/{{post.uri}}">{{post.title}}</a></h2> <p class="blog-post-meta">{{post.date}} by <a href="#">{{post.author}}</a></p> <p>{{post.announcement|safe}}</p> </div><!-- /.blog-post --> {% endfor %}</div> این ساختار بر پایه‌ی ساختار Angular.JS و DJango پیاده سازی شده است که به طور کامل پشتیبانی می‌شود.
      فعال سازی فناوری Angular.JS بر روی این سیستم جهت طراحی قالب تنها با دو دستور ساده اعمال می‌شود:
      <!-- Link to AngularJS --> <script src= "{{AngularJs}}"></script> <!-- Enable AngularJS Engine --> {{AngularJsSync|safe}} این دستورات در هسته‌ی سیستم مدیریت محتوا در کلاسی با نام Template پردازش و در نهایت به سمت HTML هندل می‌شوند.
      بخشی از دستورات سمت هسته در سی‌پلاس‌پلاس ۱۷ برای مثال ارسال عنوان صفحه به صورت زیر است:
      std::optional<std::string> LoadListTemplate::getTitle() const { if (isset(title)) { return title; } else { return std::nullopt; } } سمت HTML کافی است دستور فوق را در نظر بگیریم:
      <title>{{title}}</title> این‌ها مثال‌هایی از مراحل توسعه‌ی این سیستم است که می‌دانم آنچنان گسترده نیست، اما برای ثابت کردن طراحی و توسعه‌ی وب‌سایت تحت سی‌پلاس‌پلاس مثال‌های روشنی هستند.
       
      موفق و سربلند باشید!
      اطلاعیه‌های مربوط به این پروژه احتمالاً در کانال‌ها و گروه‌ تلگرامی و همین مرجع بازگو و در اختیار شما قرار بگیره.
    • توسط کامبیز اسدزاده
      با سلام،
      در این پست من قصد دارم به چند ویژگی استاندارد 1z اشاره کنم که به شما اجازه میده تا کُد تمیزتر، ساده‌تر و خواناتری را ایجاد کنید. توسعه زبان‌های برنامه‌نویسی روز به روز بیشتر شده و سی++ به عنوان یک زبان پیچیده نیاز به این داره تا کاربران رو از لحاظ سادگی و مدرنیزه شدن سینتکس دلگرم کنه.
      در استاندارد جدید ۱۷ من برخی از ویژگی‌ها رو معرفی می‌کنم که در تمیز نوشتن و ساده نوشتن تاثیر بسیاری دارند.
      ویژگی ساختار‌های پیوندی
      این ویژگی یکی از ویژگی‌های جدید سی++ است که امکان پیوند شدن نام‌های مشخص و زیر اشیاء المنت‌های اولیه را می‌دهد. به عبارت ساده‌تر می‌توان گفت که، ساختار‌های پیوندی (Structured Bindings) این توانایی را برای ما می‌دهد تا متغیر‌های چند گانه از یک ساختار (struct) یا tuple را به هم دیگر متصل کنیم.
      *مهمترین هدف Structured Bindings در نسخه‌ی ۱۷ ساده سازی و راحتی درک کد می‌باشد.
      سینتکس این ویژگی به صورت زیر است:
      auto ref-operator(optional)[identifier-list] = expression; // Or auto ref-operator(optional)[identifier-list]{expression}; // Or auto ref-operator(optional)[identifier-list](expression); اجازه دهید تا ما با استفاده ازیک مثال مزایای استفاده از ساختار‌های پیوندی را با کمک tuple ببینیم:
      در نسخه‌ی ۹۸ سی‌پلاس‌پلاس:
      #include <iostream> using namespace std; // Creating a structure named Point struct Point { int x; int y; }; // Driver code int main() { Point p = {1, 2}; int x_coord = p.x; int y_coord = p.y; cout << "X Coordinate : " << x_coord << endl; cout << "Y Coordinate : " << y_coord << endl; return 0; } در نسخه‌ی ۱۱ و ۱۴ سی‌پلاس‌پلاس:
      #include <iostream> #include <tuple> using namespace std; // Creating a structure named Point struct Point { int x, y; // Default Constructor Point() : x(0), y(0) { } // Parameterized Constructor for Init List Point(int x, int y) : x(x), y(y) { } auto operator()() { // returns a tuple to make it work with std::tie return make_tuple(x, y); } }; // Driver code int main() { Point p = {1, 2}; int x_coord, y_coord; tie(x_coord, y_coord) = p(); cout << "X Coordinate : " << x_coord << endl; cout << "Y Coordinate : " << y_coord << endl; return 0; }   در نسخه‌‌ی ۱۷ سی‌پلاس‌پلاس:
      #include <iostream> using namespace std; struct Point { int x; int y; }; // Driver code int main( ) { Point p = { 1,2 }; // Structure binding auto[ x_coord, y_coord ] = p; cout << "X Coordinate : " << x_coord << endl; cout << "Y Coordinate : " << y_coord << endl; return 0; } ویژگی عبارت شرطی و حلقه‌ی جدید
      نسخه‌های جدید از دستورات شرطی switch و if در سی‌پلاس‌پلاس به صورت زیر هستند:
      if (init; condition) و switch (init; condition) قبلاً شما باید به صورت زیر یک دستور شرطی را پیاده سازی می‌کردید:
      { auto val = GetValue(); if (condition(val)) // on success else // on false... } در این قالب مشخص است که val یک محدوده‌ی جداگانه و احتمال نشتی دارد. در نسخه‌ی جدید آن را می‌توان به صورت زیر ساده تر و خواناتر نوشت:
      if (auto val = GetValue(); condition(val)) // on success else // on false... در این نسخه val فقط در داخل حوزه‌ی if و else قابل مشاهده است، بنابراین در این صورت امکان نشتی نخواهد داشت. شرط ممکن است هر نوع شرط باشد و فقط وابسته به val مقدار true/false را بر نمی‌گرداند.
      خُب، چرا این نسخه مفید خواهد بود؟
      فرض کنید قرار است در داخل یک رشته چند چیز را جستجو کنید:
      const std::string myString = "My Hello World Wow"; const auto it = myString.find("Hello"); if (it != std::string::npos) std::cout << it << " Hello\n" const auto it2 = myString.find("World"); if (it2 != std::string::npos) std::cout << it2 << " World\n" ما یا باید نام‌های مختلفی را برای it استفاده کنیم و یا باید آن‌ها را در داخل دامنه‌ی جداگانه قرار دهیم. مانند مثال زیر:
      { const auto it = myString.find("Hello"); if (it != std::string::npos) std::cout << it << " Hello\n" } { const auto it = myString.find("World"); if (it != std::string::npos) std::cout << it << " World\n" } عبارت شرطی جدید if یک دامنه اضافی را فقط در یک خط ایجاد می‌کند:
      if (const auto it = myString.find("Hello"); it != std::string::npos) std::cout << it << " Hello\n"; if (const auto it = myString.find("World"); it != std::string::npos) std::cout << it << " World\n"; همانطور که قبلاً ذکر شد متغیر تعریف شده در عبارت if نیز در بلوک else قابل مشاهده است. بنابراین شما می‌توانید آن را به صورت زیر نیز بنویسید:
      if (const auto it = myString.find("World"); it != std::string::npos) std::cout << it << " World\n"; else std::cout << it << " not found!!\n"; همچنین شما در استاندارد جدید می‌توانید از ويژگی پیوند ساختاری در عبارت شرطی نیز استفاده کنید که قالب آن به صورت زیر است:
      // better together: structured bindings + if initializer if (auto [iter, succeeded] = mymap.insert(value); succeeded) { use(iter); // ok // ... } // iter and succeeded are destroyed here ویژگی Variadic Templates
      در نسخه‌ی ۱۱ ما ویژگی‌ خوبی به نام قالب‌های متنوع یا همان (Variadic Templates) داریم که بسیار عالی است، مخصوصاً وقتی که می‌خواهید با تعداد نامحدود یا متغیر با توابع کار کنید. برای مثال در نسخه‌های قبل از ۱۱ ما مجبور بودیم تا چندین تابع را با ورودی‌های مختلف پیاده سازی کنیم تا بتوانیم به نتیجه‌ی مربوطه برسیم.
      در حال حاضر این ویژگی هنوز هم نیازمند افزودن کد‌های می‌باشد مخصوصاً اگر می‌خواهید تابعی از نوع بازگشتی پیاده سازی کنید. مانند مثال زیر:
      auto SumCpp11(){ return 0; } template<typename T1, typename... T> auto SumCpp11(T1 s, T... ts){ return s + SumCpp11(ts...); } در نسخه‌ی جدید سی++۱۷ ما می‌توانیم این را بسیار ساده تر بنویسیم:
      template<typename ...Args> auto sum(Args ...args) { return (args + ... + 0); } و یا حتی ساده تر...
      template<typename ...Args> auto sum2(Args ...args) { return (args + ...); } این تابع فوق‌العاده است! ورودی‌های متغیر با نوع بازگشتی یکی از پر کاربرد‌ترین توابعی است که در نسخه‌های قبل پیاده سازی آن پیچیده بود.
      ویژگی متغیر‌های درون خطی (Inline variables)
      در قبل از سی++۱۷ ما می‌توانستیم از کلمه‌ی کلیدی inline جهت بهینه‌سازی در زمان کامپال برای توابع استفاده کنیم. حال در نسخه‌ی ۱۷ قابلیت تعریف inline برای متغیر‌ها نیز فراهم شده.
      فرض کنید قرار است متغیری را تعریف کنیم که به صورت ایستا و عمومی مورد استفاده قرار بگیرد. در قبل از نسخه‌ی ۱۷ تعریف آن به این صورت که متغیر در فایل هدر و سورس اعلان و تعریف شوند:
      #ifndef MYCLASS_H #define MYCLASS_H class MyClass { public: MyClass(); static const int myVariable; }; #endif // MYCLASS_H فایل سورس
      #include "myclass.h" MyClass::MyClass() { } const int MyClass::myVariable = 17; و در نهایت تابع و فایل main:
      #include <iostream> #include "myclass.h" int main() { std::cout << "My global variable is : " << MyClass::myVariable << std::endl; return 0; } در استاندارد جدید تعریف تابع در همان زمان اعلان به صورت ایستا و عمومی امکان پذیر شده است. برای مثال:
      #ifndef MYCLASS_H #define MYCLASS_H class MyClass { public: MyClass(); inline static const int myVariable = 17; }; #endif // MYCLASS_H همین تعریف برای اعلان متغیر از نوع ایستا و عمومی کافی است. این کار باعث می‌شود نیازی برای تعریف مقدار متعیر در فایل سورس نباشد.
      مثال‌های دیگر :
      struct MyClass { static const int sValue; }; inline int const MyClass::sValue = 777; و یا ساده تر از آن به شکل زیر:
      struct MyClass { inline static const int sValue = 777; };  
    • توسط کامبیز اسدزاده
      با سلام،
      با توجه به سوالات مکرر برخی از کاربران و خصوصاً دانشجویان جدید، تصمیم گرفته شد تا توضیحاتی درباره‌ی نحوه‌ی یادگیری برنامه‌نویسی با سی‌پلاس‌پلاس بیان شود.
       
      مقدمه
      در حال حاضر بیش از سه دهه است که از ساخت و معرفی زبان برنامه‌نویسی ++C می‌گذرد. در رابطه با آن‌ که هدف از ایجاد این زبان چه چیزی بوده و مزایای آن نسبت به زبان‌های دیگر چه چیزی است را می‌توانید در این تاپیک را مطالعه کنید. اما بسیاری از افراد علاقه‌مند به زبان‌های برنامه‌نویسی تمایل بسیاری دارند تا در برنامه‌نویسی با این زبان به درجه مطلوب و درواقع (حرفه‌ای) برسند. قبل از هر چیز باید مواردی را در نظر داشته باشیم که یاد گیری زبان‌های برنامه‌نویسی به خودی خود کافی نیست! مخصوصاً زبان‌‌های C و ++C مستلزم پیش‌نیاز‌های تخصصی بسیاری هستند که در روند تولید، توسعه، تجزیه و تحلیل رفتار کامپایلر و سیستم‌عامل بسیار مهم است.
       
      در ادامه ما به سوالاتی که معمولاً توسط تازه‌کاران پرسیده شده است پاسخ داده ایم:
      قبل از رسیدن به پاسخ سوالات خود به این نکته حتماً توجه کنید که زبان‌های برنامه‌نویسی بسیاری وجود دارد که ممکن است بدون داشتن اطلاعات تخصصی در رابطه با سیستم‌عامل، کامپایلر، انواع معماری‌های سیستمی و غیره موفق به یادگیری آن‌ها شوید. اما در این میان زبان سی++ چنین ویژگی‌ای ندارد (کاربر را به چالش می‌کشد) و شما باید قبل از زبان به عنوان پیش نیازات یادگیری و درک آن از مباحث مهندسی نرم‌افزار، سیستم‌عامل (ساختار و معماری آن)، ساختار و معماری کامپایلر‌ها و رفتار‌های آن‌ها، سخت‌افزار و نوع معماری پردازنده‌ها و موارد این چنین آشنا شوید. کاملاً روشن است که یادگیری چنین مباحثی سنگین بوده و بدون شک شما باید در حوزه‌ی مهندسی کامپیوتر به خصوص نرم‌افزار کسب علم نمایید.
       
      ابعاد علمی و اقتصادی کار با ++C/C در ایران
      متاسفانه اکثر ما ملتی هستیم، تَنبَل و حاضر برای لُقمه‌ی آماده 😋 بنابراین بازار کار در ایران به گونه‌ای است که بیشتر شرکت‌ها و افراد توسعه دهنده به سراغ زبان‌های ساده‌تر و در دسترس‌تر (بی دردسر) می‌روند. غافل از آن که یک برنامه‌ی تولید شده توسط سی++ بسیار سریع، جذاب، قدرتمند و انعطاف‌پذیر تر است. تمامی مساله در اینجا تمام نمی‌شود، چرا که شاید در سال‌های اخیر وضعیت تقریباً فرق کرده و به کمک اطلاع رسانی‌های اساتید و دوستان حرفه‌ای ما در این زمینه این اطلاع رسانی به خوبی صورت گرفته و توسعه دهنده‌ها از قابلیت‌ها پنهان این زبان آگاه شده اند. شرکت‌ها و گروه‌های برنامه‌نویسی بسیاری به دنبال برنامه‌نویس‌های سی++ و کیوت هستند که این امر نشان دهنده‌ی این است که نسبت به سال‌های گذشته پیشرفت و آگاهی جامعه در این حوزه منطقی تر و بهتر شده است.
      بنابراین، بهتر است قبل از هرچیز در نظر داشته باشید که هدف از این تاپیک، این نیست که اثبات کنیم یک زبان نسبت به زبان دیگر برتری دارد. هدف اصلی ما این است به واقعیت‌هایی اشاره کنیم که غیر منطقی نیستند. چرا که واقعاً کارفرمایانی وجود دارند که نیازمند به برنامه‌نویسانی هستند که تخصص خوبی در زبان‌های برنامه‌نویسی دیگری مانند سی و سی++ دارند. متاسفانه در کشور ما اینگونه است که به ازای مثلاً هر ۱۰۰ نفر سی‌شارپ کار یا زبان‌های دیگر ۱ نفر سمت سی++ می‌رود! و این روند برای توسعه صنعت نرم‌افزاری کشور که بسیاری از کارفرمایان به آن نیاز دارند ضربه‌ی سختی وارد می‌کند.
      توجه داشته باشید که هدف از این توضیحات چنین نیست که بعد از خواندن این مطالب زبان برنامه‌نویسی مورد علاقه‌ی خود را کنار گذاشته و به سمت سی++ بروید، خیر! تمامی زبان‌ها به عنوان ابزار‌های کاری شما در یک جعبه‌ی ابزار هستند و هر زبانی حوزه‌ی کاربردی خودش را دارد. بنابراین قبل از اینکه شما تصمیم بگیرید که چه زبانی را یاد خواهید گرفت باید حوزه‌ی کاری وعلاقه‌ی خودتان را مشخص کنید سپس وارد تحقیق و بحث و نظر خواهی راجع به آن زبان نمایید. بنابراین مقایسه‌ی زبان طبق این قانون کاملاً کار اشتباه و بچه‌گانه است.
      متاسفانه به خاطر تفکرات اشتباه و معرفی‌های غیر منطقی و  غیر علمی برنامه‌نویسان کشور ما که ممکن است حتی خودِ شما هم چنین تصور کنید، در رابطه با سایر زبان‌ها مانند سی++ بسیاری از کارفرمایان نیازمند چنین برنامه‌نویسانی هستند که در کشور ما واقعاً نیاز است. توجه داشته باشید که انتخاب درست این نیست که چون همه سراغ سی‌شارپ می‌روند و چون تمامی آگهی‌ها استخدامی مرتبط با سی‌شارپ است پس فقط باید این زبان را یاد گرفت و تمام! خیر چنین تفکری اشتباه است و ضربه‌ی بسیار بزرگی در صنعت و دانش آینده‌ی کشور خواهد زد.
          *نکته‌ی مهم و جالبی که وجود دارد این است که در خارج از کشور بیشترین دست‌مُزد متعلق به برنامه‌نویسان سی++ می‌باشد. در کشور ما برنامه‌نویسان این زبان دست‌مُزد مناسبی می‌توانند بگیرند اما به هیچ عنوان قابل مقایسه با دستمزد‌های خارج از کشور نیست (اما خارج از بحث اقتصادی حال حاضر ممکن است قابل تأمل باشد).
      نکاتی در این میان وجود دارد که باید به آن‌ها اشاره کرد:
      متاسفانه در کشور ما بسیاری از برنامه‌نویسان چه مبتدی چه حرفه‌ای اینطور تصور می‌کنند که تولید محصول نرم‌افزاری یعنی برنامه‌نویسی یک نرم‌افزار که قرار است به بانک اطلاعاتی متصل شده و کار‌هایی مانند ثبت و ویرایش اطلاعات و در نهایت گزارش گیری و دیگر عملیات ممکن را انجام دهد! این تفکر به شدت اشتباه است! بسیاری از بانک‌ها و شرکت‌های صنعتی و اقتصادی مهم کشور نیازمند برنامه‌نویسان سی++ هستند تا بتوانند در بحث بانکی برای توسعه دستگاه‌های پرداخت مانند Pos و ATM از این زبان‌ و برنامه‌نویسان بهره‌ ببرند. در صنایع بزرگ خودرو سازی یا پرس و دیگر موارد نرم‌افزار‌های مورد نیاز است تا با سرعت بسیار و بدون محدودی پلتفرمی پاسخگوی یک چرخه‌ی تولید باشند تا بتواند یک شرکت بزرگ را مدیریت و آن را بهینه کند. در بسیاری از حوزه‌های صنعتی کشور شرکت‌های غول‌پیکر در زمینه‌ی تولیدات انبوه و سنگین که توسط ماشین‌آلات صورت میگیرد به دنبال برنامه‌نویسان سی و سی++ هستند که ممکن است به صورت معرف یا آشنا با آن‌ها مواجه و استخدام شوید. شرکت‌های سخت‌افزاری و استارت‌آپ‌هایی که در حوزه‌ی الکترونیک و سخت‌افزار فعالیت می‌کنند به دنبال برنامه‌نویسیان سی++ هستند تا بتوانند در حوزه‌ی کاری خود اهداف خود را توسعه و شما را به عنوان مهره‌ای مفید پیش ببرند. شرکت‌های توسعه‌دهنده‌ی موبایل و خطوط تولیدی تلفن‌های همراه داخلی گسترش یافته و به شدت نیازمند برنامه‌نویسان سی++ هستند که برخی از آن‌ها مبادلات بین‌المللی نیز دارند. در بخش حوزه‌ی شهر سازی، مدیرت شهر و همچنین راه‌‌‌داری شرکت‌هایی هستند که برای تولید سیستم‌های مدیریتی مانند مدیریت راه‌ها و تردد‌های خودرو و یا مدیریت ترافیک و موارد این چنینی به دنبال برنامه‌نویسان سی++ هستند. بسیاری از شرکت‌ها و حتی تیم‌های توسعه بر روی پلتفرم‌های iOS و Android به صورت تخصصی  سفارشی سازی و حتی ساخت و توسعه‌ی اپلیکیشن‌های ایرانی تمرکز دارند که جدیداً به لطف آگاهی از فریم‌وُرک‌هایی مانند Qt به سمت این حوزه آمده و نیازمند سی++ کاران هستند. شرکت‌های بازی‌سازی کشور ما که این سال‌ها با پیشرفت‌های خوبی مواجه شده‌اند به دنبال برنامه‌نویسان سی++ هستند که بتوانند در این صنعت برای فرهنگ‌سازی و توسعه صنعت بازی سازی جلو بروند. بسیاری از شرکت‌های پنهان وجود دارد که به صورت بسیار مخفیانه در صنایع سه‌بعدی و پیشرفته‌ در حال فعالیت‌ هستند که محصولات خود را نه در ایران بلکه در خارج از آن آمریکا و دیگر کشور‌های اروپایی به فروش می‌رسانند که به سفارش آن‌ها بوده است. با دید سطحی به این مسائل نباید نگاه کنید، اگر آگهی‌های استخدامی نمیبینید به خاطر این است که این زبان کار کُن می خواهد نه تَنبل! بنابراین شما باید به سراغ آن بروید چرا که بسیاری از شرکت‌های بین‌المللی فعالیت‌های بزرگی انجام می‌دهند که هیچوقت از آن‌ها خبر ندارید و به صورت کاملاً سفارشی و حساسیت کامل به دنبال برنامه‌نویسان این زبان هستند (چون می‌دانند یک سی++ کار هدفمند و با دید بازتری به توسعه نگاه می‌کند). چنین شرکت‌ها معمولاً استخدام را به صورت رابطه‌ای انجام می‌دهند و تعداشان هم کم نیست. ما می‌دانیم که شاید شما با دیدگاه اینکه حتماً باید نرم‌افزار‌های کاربردی تولید کنید به قضیه نگاه می‌کنید، خوشبختانه فریم‌ورک‌ کیوت به قدری قدرتمند و پُخته شده است که می‌توان هر محصول کاربردی در هر زمینه‌ای را تولید کرد که از کارایی بسیار بهتری نسبت به دات نت بهره‌مند است. در حوزه‌ی امنیت، شبکه و موارد این چنینی شرکت‌های بزرگ و Isp‌ها نیازمند این زبان هستند. نکته‌ی قابل توجه این که، اگر در کشور ما از چند صد هزار نفر برنامه‌نویس سی‌شارپ کار یک برنامه‌نویس سی++ کار وجود داشته باشد باید امیدوار باشیم که همان درصد محدود و ناچیز راه درستی را رفته‌اند! البته دلایل بسیاری وجود دارد که موجب می‌شود شرکت‌ها از روی ناچاری به سراغ برنامه‌نویسان دیگر بروند، که من شخصاً آن را تجربه کرده ام ! در بسیاری از پروژه‌ها که به عنوان مشاور فنی در آن‌ها شرکت کرده بودیم متوجه آن شدیم شرکت‌ها به خاطر عدم وجود برنامه‌نویس سی++ برای ادامه‌ی چرخه‌ی تولید خود مجبوراً سراغ برنامه‌نویس‌های دیگر زبان‌ها می‌روند. این امر به خاطر این است که واقعاً درصد تعداد برنامه‌نویسان این زبان نسبت به زبان‌های دیگر به خاطر (راحت طلبی) و شاید عدم آگاهی از این زبان دور هستند. برخی از سوالاتی که علاقه‌مندان به این حوزه می‌پرسند در ادامه آمده است:
      من یک دانشجو هستم و رشته‌ی تحصیلی من کامپیوتر است، به برنامه‌نویسی با ++C علاقه دارم از کجا باید شروع کنم؟
      اگر شما به قصدِ حرفه‌ای شدن دنبال یادگیری این زبان هستید، همانطور که اشاره‌ای شد مباحث پیش نیاز برای یادگیری این زبان مهم هستند و برای درک هرچه بیشتر این زبان بهتر است دانش خوبی در زمینه‌ی تجزیه و تحلیل رفتار کامپایلر داشته باشید. علاوه بر این برای آشنایی با کامپایلر رفتار سیستم‌عامل و واکنش‌های کامپایلری در سیستم‌عامل‌های متفاوت بسیار مهم است. به عنوان مثال کامپایلر GCC بر روی ایستگاه‌های یونیکس تعبیه شده و برای خود قوانین و استاندارد‌هایی را دارد. در کنار آن کامپایلر MSVC نوعی کامپایلر اختصاصی تحت ویندوز است که متناسب با ساختار و معماری ویندوز رفتار می‌کند.
      من یک دانشجو هستم اما متاسفانه رشته‌ی تحصیلی من کامپیوتر نیست، به برنامه‌نویسی با ++C علاقه دارم از کجا باید شروع کنم؟
      این کار کمی دشوار است، در مرحله‌ی اول پیشنهاد ما این است که سراغ زبان‌های برنامه‌نویسی دیگری بروید که نیازی نداشته باشد شما درگیر درک کامپایلر یا رفتار‌های سیستم‌عاملی شوید. اما به هر حال اگر شما به هر نحوی می‌خواهید این زبان را یاد بگیرید چاره‌ی کار تلاش مستمر و حوصله است. متاسفانه سی‌پلاس‌پلاس ذاتی مرموز دارد و آن این است که اگر بتوانید به آن مسلط شوید یک زبان با وفا و قدرتمندی خواهد بود که در هر زمینه‌ای به نیاز‌های شما پاسخگو خواهد شد. اما اگر به هر دلیلی نتوانید با این زبان دوست شوید به طور بسیار مرموزی اعصابتان را به هم خواهد ریخت 🙂 که البته طبیعی است چون سی++ تحت کامپایلر‌های خود دستِ برنامه‌نویس را آزاد گذاشته و شما هستید که انتخاب می‌کنید کُد شما به چه شیوه‌ای با توجه به هدف چگونه عمل کند. 
      چقدر زمان لازم است تا من این زبان برنامه‌نویسی را یاد بگیرم؟
      با توجه به ساختار زبان و رفتار‌های کامپایلر می‌توان گفت به قدری دامنه‌ی سی++ گسترده است که تنها راه حل ممکن برای رسیدن به یک وضعیت مطلوب از دانش مرتبط با آن باید زمان مشخصی در نظر گرفته شود. ممکن است شما بتوانید در بازه‌ی ۱ الی ۳ ماه مباحث مقدماتی این زبان را درک کنید. اما توجه داشته باشید پیش‌نیازات آن نیز نیازمند تحقیق، تجربه عملی و نتیجه‌گیری تئوری و علمی هستند. با توجه به اینکه شما (سریع، هوشمند با گیرایی بالا باشید) می‌توانید در کمتر از ۶ ماه به یک پایداری تقریباً قابل قبول در حد مقدماتی این زبان برسید. استاندارد زبان را درک کنید و نحوه‌ی برقراری ارتباط با کتابخانه‌های پیشفرض STL و غیره را تجربه کنید. برای کسب دانش و افزایش آن به میزان متوسط و به بالا نیازمند تلاش بسیار بیشتری خواهید بود که باید در قالب پروژه‌های عملی و واقعی صورت گیرد. متاسفانه سی++ به دلیل گسترده‌ بودن چنان پیچیدگی‌هایی را دارد که تنها می‌توان در موقع برنامه‌نویسی به صورت عملی (بر روی پروژه‌های واقعی) آن را تجربه کرد.
      آیا ارزش دارد من این زبان را یاد بگیرم؟ فرصت من کم است و می‌خواهم سریعاً به درآمد زایی برسم
      اگر شما به عنوان یک برنامه‌نویس متوسط و به بالا به این زبان تسلط دارید، و حداقل می‌توانید با یکی از کتابخانه‌های خوب آن ارتباط برقرار کنید باید به شما تبریک گفت. وقت آن است که با کتابخانه‌های قدرتمند این زبان وارد عمل شوید. کتابخانه‌هایی مانند Boost، Poco، Qt و غیره از سری کتابخانه‌هایی می‌باشد که امکانات بسیاری را در اختیار شما علاقه‌مندان این زبان قرار می‌دهند تا بتوانید در کمترین زمان ممکن به نیاز‌های خود دسترسی داشته و آن را پیاده سازی کنید.
      توجه داشته باشید که لازمه‌ی طراحی و توسعه یک محصول مفید (قابل قبول) در قالب MVP (کمینه محصول پذیرفتنی) مستلزم داشتن دانش طراحی محصول نیز می‌باشد. اما همه چیز اینگونه خلاصه نشده است و شما برای اینکه بتوانید یک محصول واقعاً قابل قبول را پیاده سازی کنید مسلماً باید آن را مجهز به قابلیت‌های دیگری مانند منابع ذخیره‌ داده و یا سرویس‌ها و ماژول‌هایی کنید که بتواند به عنوان یک محصول کاربردی روی آن حساب کرد. کاملاً روشن است که علاوه بر پیش‌نیازاتی که به آن‌ها در بالا اشاره شده است، داشتن دانش در رابطه با SQL، معماری وب سرویس‌ها و ساختار Api ها، طراحی رابط کاربری تحتِ Xml، QML، JavaScript و حتی شبکه و اینترنت نیاز خواهد بود.
      با توجه به این موارد اگر بخواهید محصولی را بسازید که طبق استاندارد‌ آن را توسعه و تولید کنید باید ابزار‌ها و موارد پیشنهادی زیر را در اختیار داشته و به تک به تک آن‌ها مسلط باشید:
      یک محیط توسعه یکپارچه‌ی نرم‌افزار مانند Qt Creator، Xcode یا Visual Studio (پیشنهاد ما Qt Creator است). پلتفرم توسعه (سیستم‌عاملی) که قرار است محیط توسعه‌ی یکپارچه خود را بر روی آن نصب و شروع به برنامه‌نویسی کنید را مشخص نمایید. اگر شما کاربر ویندوز هستید باید محیط توسعه‌ی یکپارچه‌ی شما مجهز به کامپایلر MSVC و یا نسخه‌ی پورت شده‌ی GCC یعنی MinGW باشد. اگر شما کاربر مک‌او‌اِس هستید به صورت پیشفرض با نصب محیط توسعه کامپایلر Clang بر روی آن تعبیه خواهد شد. البته می‌توانید به صورت سفارشی از کامپایلر GCC نیز استفاده کنید. در صورتی که کاربر لینوکس هستید کامپایلر GCC به صورت پیشفرض بر روی محیط توسعه‌‌ی شما تعبیه خواهد شد. بر اساس پیشنهاد ما جهت محیط توسعه‌ کتابخانه‌ی Qt نیز پیشنهاد می‌شود (دلیل آن این است که این کتابخانه به شما کمک می‌کند تا بتوانید رابط کاربری نرم‌افزار (محصول) خود را پیاده سازی کنید). اگر هدف شما طراحی یک محصول استانداردی است که از شکل و ظاهر آن‌چنانی برخوردارد نیست بهتر است از ماژول‌های پیشفرض Qt مانند Qt Widget برای طراحی آن استفاده کنید. این کار بسیار ساده است و نیازی برای داشتن دانش در رابطه با حوزه‌های JavaScript و QML ندارد. البته می‌توانید با ترکیب CSS طراحی رابط کاربری برنامه‌ی خود را بهبود ببخشید. بعد از این موارد نیاز است که شما هدف توسعه‌ی خود را مشخص کنید، اینکه می‌خواهید توسعه دهنده‌ی چه پلتفرمی باشید؟ تولید کننده برنامه‌های دسکتاپ بر روی ویندوز؟ یا لینوکس و مک؟ یا همه‌ی آن‌ها؟ خوشبختانه با توجه به قابلیت‌های ذاتی سی++ و کیوت شما می‌توانید برنامه‌ی خود را تنها با داشتن محیط توسعه‌ی خود بر روی پلتفرم مورد نظر خود کامپایل و خروجی بگیرید (البته به شرط اینکه از سرویس‌های اختصاصی سیستم‌عاملی) استفاده نکرده باشید. اگر مشتاق آن هستید که برای پلتفرم‌های موبایل مانند آی‌او‌اس یا اندروید برنامه تولید کنید، قضیه کمی گسترده تر خواهد شد و حتماً باید ملزوماتی که در ابتدای مقاله به آن اشاره شده است را در نظر داشته باشید. برای مثال تولید یک اپلیکیشن آی‌او‌اس مستلزم آن است که شما علاوه بر داشتن دانش سی++ در رابطه با معماری و ساختار و همچنین قوانین سیستم‌های مرتبط با اپل را اطلاعات کافی داشته باشید. در اندروید نیز این چنین است. اگر شما تازه کار هستید پیشنهاد می‌کنیم هدف خود را فعلاً محدود بر یک پلتفرم خاص کنید، برای مثال توسعه محصول بر روی ویندوز برای آغاز کار بسیار مناسب است. در نهایت شما محصول خود را با آزمایش وخطا‌های بسیاری می‌توانید تولید و با توجه به مستنداتی که در همین مرجع ارائه شده است می‌توانید مستقر و برای کاربر مورد نظر ارائه دهید.  برای اینکه بدانید مزایای این زبان در چیست و چه کتابخانه‌هایی می‌توانند مفید باشد و برخی از سوالات احتمالی که ممکن است به ذهن شما برسد این بخش را مطالعه کنید. برای نحوه‌ی شروع کار با Qt این بخش را مطالعه کنید. جهت نحوه‌ی نصب و راه اندازی محیط توسعه این بخش را مطالعه کنید.
×