अंतिम अद्यतन:2026-10-12
C++17 सत्तरह उन्नत विशेषताएँ¶
C++17 की 17 उन्नत विशेषताओं की पूरी समीक्षा¶
C++17 आजकल बहुत उपयोग किए जाने वाले संस्करणों में से एक है, आज समय निकालकर 17 महत्वपूर्ण विशेषताओं को व्यवस्थित करते हैं, सभी विशेषताएँ इतनी से बहुत अधिक हैं।
1. समानांतर एल्गोरिद्म¶
C++17 ने स्टैंडर्ड लाइब्रेरी के कई एल्गोरिद्मों के समानांतर संस्करण पेश किए। ये एल्गोरिद्म समानांतर में निष्पादित हो सकते हैं, इसलिए मल्टी-कोर सिस्टम पर इनसे उल्लेखनीय परफ़ॉर्मेंस सुधार मिल सकता है।
पहले इस विशेषता की पूरी जानकारी देने वाला एक लेख लिखा था, वह देखें:
उदाहरण:
#include <algorithm>
#include <vector>
#include <execution>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::sort(std::execution::par, v.begin(), v.end());
}
इस उदाहरण में, std::sort समानांतर रूप से निष्पादित होता है, वेक्टर v के तत्वों को समानांतर तरीके से क्रमबद्ध करता है।
2. If Initializers¶
C++17 का If initializer एक विशेषता है, जो if स्टेटमेंट में सीधे वेरिएबल आरंभ करने की अनुमति देता है। यह आरंभीकरण तरीका कुछ हद तक कोड की पठनीयता और संक्षिप्तता बढ़ाता है।
पारंपरिक C++ में, हम प्रायः वेरिएबल ऐसे आरंभ करते थे:
जबकि C++17 में, if initializer का उपयोग करके इस प्रक्रिया को सरल बनाया जा सकता है, जिससे कोड अधिक संक्षिप्त हो जाता है:
इस उदाहरण में, हमने वेरिएबल x का आरंभीकरण सीधे if स्टेटमेंट में रखा है। वेरिएबल condition, if स्टेटमेंट में परिभाषित और आरंभित होता है, और फिर if ब्लॉक में उपयोग योग्य होता है। यह तरीका अधिक सहज और संक्षिप्त है, खासकर सरल conditional आरंभीकरण में।
3. क्लास टेम्प्लेट आर्ग्युमेंट डिडक्शन (CTAD)¶
CTAD कंपाइलर को फ़ंक्शन पैरामीटर से टेम्प्लेट पैरामीटर का स्वतः अनुमान लगाने देता है। इससे टेम्प्लेट पैरामीटर स्पष्ट रूप से बताए बिना टेम्प्लेट का उपयोग करना आसान हो जाता है।
इस विशेषता पर पहले लिखा विस्तृत लेख:
उदाहरण:
इस उदाहरण में, जब foo(42) कॉल होता है, तो कंपाइलर T का प्रकार int अनुमानित करता है।
4. template <auto>¶
टेम्प्लेट कीवर्ड को non-type टेम्प्लेट पैरामीटर के प्लेसहोल्डर के रूप में पेश किया गया। यह टेम्प्लेट में किसी भी प्रकार के मान को व्यक्त करने की अनुमति देता है।
उदाहरण:
template<auto value>
struct constant {
static constexpr auto get_value() { return value; }
};
// 用法
static_assert(constant<42>::get_value() == 42);
5. std::optional और std::variant¶
std::optional और std::variant, C++17 में पेश दो नए प्रकार हैं। std::optional एक ऐसे मान को दर्शाता है जो हो भी सकता है और नहीं भी, जबकि std::variant एक type-safe union है, जो भिन्न प्रकारों के मान रख सकता है।
उदाहरण:
#include <optional>
#include <variant>
int main() {
std::optional<int> opt = 42;
std::variant<int, double> var = 3.14;
}
इस उदाहरण में, opt मान 42 रखने वाला optional पूर्णांक है, और var मान 3.14 रखने वाला variant है।
6. फ़ोल्ड एक्सप्रेशन¶
C++17 में, फ़ोल्ड एक्सप्रेशन पैरामीटर पैक पर बाइनरी ऑपरेशन निष्पादित करने का एक संक्षिप्त तरीका देते हैं। ये स्पष्ट recursion या iteration की ज़रूरत के बिना, पैरामीटर पैक के तत्वों का योग, गुणन या जोड़ना जैसे ऑपरेशन निष्पादित करने की अनुमति देते हैं।
उदाहरण के लिए:
#include <iostream>
template<typename T>
T sum(T t) {
return t;
}
// 使用折叠表达式的递归情况
template<typename T, typename... Args>
T sum(T first, Args... args) {
return first + sum(args...);
}
int main() {
int total = sum(1, 2, 3, 4, 5);
std::cout << "总和: " << total << std::endl;
return 0;
}
रिकर्सिव sum फ़ंक्शन में फ़ोल्ड एक्सप्रेशन (first + ... + args) पैरामीटर पैक के हर तत्व पर जोड़ ऑपरेशन लागू करता है।
7. स्ट्रक्चर्ड बाइंडिंग्स¶
स्ट्रक्चर्ड बाइंडिंग्स आपको किसी ऑब्जेक्ट को उसके घटक तत्वों में विभाजित करने की अनुमति देती हैं, ठीक वैसे जैसे आप tuple unpacking करते हैं।
पहले का लेख:
उदाहरण:
#include <tuple>
#include <string>
int main() {
std::tuple<int, std::string, double> t(42, "hello", 3.14);
auto [i, s, d] = t; // i = 42, s = "hello", d = 3.14
}
इस उदाहरण में, स्ट्रक्चर्ड बाइंडिंग [i, s, d], tuple t को उसके घटक तत्वों में विभाजित करती है।
8. टेम्प्लेट टेम्प्लेट पैरामीटर¶
उदाहरण के लिए: C++17 में, सिंटैक्स template<template<class...>typename bob> struct foo {} एक foo नाम का टेम्प्लेट घोषित करता है, जो bob नाम का टेम्प्लेट टेम्प्लेट पैरामीटर लेता है। टेम्प्लेट टेम्प्लेट पैरामीटर bob स्वयं किसी भी संख्या में टेम्प्लेट प्रकार पैरामीटर लेता है।
template <template<class...> typename bob>
struct foo {
template<typename T>
void bar(const bob<T>& arg) {
std::cout << "size: " << arg.size() << std::endl;
}
};
int main() {
foo<std::vector> f;
std::vector<int> vec = {1, 2, 3, 4, 5};
f.bar(vec);
return 0;
}
main फ़ंक्शन में, हमने std::vector से foo को instantiate किया, इसे bob के टेम्प्लेट पैरामीटर की तरह। इससे हम एक सामान्य संरचना foo बना पाते हैं, जो किसी भी ऐसे टेम्प्लेट के साथ काम कर सकती है जो किसी भी संख्या में प्रकार पैरामीटर लेता हो, जैसे std::vector, std::list या उपयोगकर्ता-परिभाषित टेम्प्लेट।
9. इनलाइन वेरिएबल¶
C++17, क्लास की परिभाषा के भीतर वेरिएबल को inline परिभाषित करने की अनुमति देता है, जिससे binary आकार छोटा करने में मदद मिलती है, और कई translation unit में वेरिएबल की दोहरी प्रतियाँ रोककर परफ़ॉर्मेंस बढ़ सकती है।
उदाहरण:
class MyClass {
public:
inline static int inlineVar = 42;
};
int main() {
int localVar = MyClass::inlineVar;
}
यहाँ, inlineVar, MyClass का inline static मेंबर वेरिएबल है।
10. एट्रिब्यूट सुधार¶
C++17 नए एट्रिब्यूट देता है और पहले से मौजूद एट्रिब्यूट सुधारता है, जिससे डेवलपर कंपाइलर को कोड व्यवहार की अधिक जानकारी दे सकते हैं।
उदाहरण:
[[nodiscard]] int get_sum(int a, int b) {
return a + b;
}
int main() {
auto result = get_sum(1, 2);
// 编译器可能会警告‘result’未使用
}
इस उदाहरण में, [[nodiscard]] एक एट्रिब्यूट है जो फ़ंक्शन पर लागू हो सकता है, यह दर्शाता है कि उसकी रिटर्न वैल्यू को कॉल करने वाले को नज़रअंदाज़ नहीं करना चाहिए।
11. नेस्टेड नेमस्पेस¶
C++17 ने वैरिएडिक टेम्प्लेट को फ़ोल्ड एक्सप्रेशन से सुदृढ़ किया, जिससे पैरामीटर पैक से निपटते समय कोड अधिक संक्षिप्त और स्पष्ट होता है।
उदाहरण:
// 外部命名空间
namespace outer {
// 内部命名空间
namespace inner {
void foo() {
std::cout << "在内部命名空间中" << std::endl;
}
}
}
outer::inner::foo();
नेस्टेड नेमस्पेस परिभाषा कोड को पदानुक्रमित रूप से व्यवस्थित करने का तरीका देती है, जिससे पठनीयता और रखरखाव बढ़ता है, खासकर बड़े प्रोजेक्ट्स में। ये अधिक संरचित नेमस्पेस पदानुक्रम देकर नाम टकराव से बचने में भी मदद करती हैं।
12. लिटरल सुधार¶
C++17 ने लिटरल सुधारे, जिनमें पूर्णांक और फ़्लोटिंग-पॉइंट लिटरल में सुधार शामिल है, साथ ही true और false लिटरल का समर्थन भी।
उदाहरण:
auto num = 123_456; // Underscore in integer literals
auto pi = 3.1415_f; // Suffix for floating-point literals
13. constexpr Lambda¶
C++17, lambda फ़ंक्शन के constexpr होने की अनुमति देता है, यदि वे शर्तें पूरी करते हों, तो उन्हें compile-समय मूल्यांकन वाले संदर्भों में उपयोग किया जा सकता है, उदाहरण के लिए:
इस उदाहरण में, lambda एक constexpr lambda है, जो पैरामीटर के रूप में पूर्णांक x लेता है और x का दोगुना लौटाता है। static_assert compile समय पर जाँचता है कि lambda(5) का मान 10 के बराबर है या नहीं।
14. *this कैप्चर करना¶
lambda में *this को कैप्चर करना और भी सरल हो गया, जिससे समाहित ऑब्जेक्ट के मेंबर्स तक सीधी पहुँच मिलती है।
class Foo {
int data = 42;
public:
auto member_lambda() {
return [*this] { std::cout << data << std::endl; };
}
};
// 使用
Foo f;
f.member_lambda()(); // 输出 "42"
15. विस्तारित if और switch स्टेटमेंट¶
if या switch स्टेटमेंट में शर्त अब कोई भी एक्सप्रेशन हो सकती है, केवल बूलियन शर्त तक सीमित नहीं। इससे control flow अधिक लचीला होता है, जैसे स्ट्रक्चर्ड बाइंडिंग का उपयोग करते समय:
इस उदाहरण में, if स्टेटमेंट जाँचता है कि inserted वेरिएबल सत्य है या नहीं, लेकिन शर्त में स्ट्रक्चर्ड बाइंडिंग का असाइनमेंट भी शामिल है।
16. सामान्यीकृत range-based for लूप¶
यह सुधार begin iterator के प्रकार से भिन्न साइन या end iterator का समर्थन करता है, जो null-terminated लूप और ऐसे ही अन्य मामलों से निपटने में मदद करता है। उदाहरण के लिए:
इस उदाहरण में, my_container संभवतः ऐसा कंटेनर है जो भिन्न प्रकार का end iterator उपयोग करता है, फिर भी लूप सही ढंग से काम करता है।
17. if constexpr¶
यह विशेषता कंपाइलर को compile समय पर शर्त का मूल्यांकन करने की अनुमति देकर अधिक सामान्य कोड लिखने लायक बनाती है। यदि शर्त सत्य है, तो compile किए गए कोड में if ब्लॉक का कोड शामिल होता है; अन्यथा वह हटा दिया जाता है। इससे runtime पर अनावश्यक शाखाएँ हटाकर कोड सरल होता है। उदाहरण के लिए:
इस उदाहरण में, if constexpr स्टेटमेंट जाँचता है कि प्रकार T, int है या नहीं, और उसी अनुसार उपयुक्त कोड शामिल करता है।
सारांश¶
इस सेक्शन में इतना ही, बाक़ी सामग्री अगले सेक्शन में प्रस्तुत की जाएगी।
संबंधित विषय¶
- C++17 [[nodiscard]] एट्रिब्यूट | C++那些事
- C++17 std::string_view | C++那些事
- C++17 PMR मेमोरी रिसोर्सेज़ | C++那些事
- C++17 क्लास टेम्प्लेट आर्ग्युमेंट डिडक्शन CTAD | C++那些事
- C++17 optional_ref | C++那些事
- C++17 std::variant | C++那些事
- C++17 स्ट्रक्चर्ड बाइंडिंग्स | C++那些事
- C++17 टेम्प्लेट auto डिडक्शन | C++那些事
- C++17 वेरिएबल टेम्प्लेट्स | C++那些事