std::apply on std:: کا استعمال C++23 میں متوقع ہے۔

C++

C++23 میں سٹریم لائننگ ایرر ہینڈلنگ

آج کی C++ ترقی میں غلطیوں کو مؤثر طریقے سے سنبھالنا اور واپسی کی قدروں کا نظم کرنا ضروری ہے۔ فنکشنز کے ساتھ کام کرنے کے عام طریقہ جو کہ {std::expected} قسمیں واپس کرتے ہیں اس میں بہت سارے چیک اور ایرر ہینڈلنگ کوڈ شامل ہیں، جو منطق کو پیچیدہ بنا سکتے ہیں اور کوڈ کو برقرار رکھنا مزید مشکل بنا سکتے ہیں۔

یہ مقالہ غلطی کے انتظام کو آسان بنانے کے لیے زیادہ نفیس اور عمومی طریقہ کار کے استعمال کی تحقیقات کرتا ہے۔ بوائلر پلیٹ کوڈ کو کم کرنے اور پڑھنے کی اہلیت کو بہتر بنانے کے لیے، ہم ایک `magic_apply` طریقہ بنانے کی چھان بین کریں گے جو بہت سے {std::expected} اقدار کے نتائج کو جمع کرتا ہے اور انہیں کسی دوسرے فنکشن میں منتقل کرتا ہے۔

حکم تفصیل
std::expected غلطی سے نمٹنے کے لیے C++ میں استعمال ہونے والی ٹیمپلیٹ کی قسم جس میں اقدار اور غلطیوں دونوں کو ذخیرہ کرنے کی صلاحیت ہوتی ہے۔
std::unexpected std::expected کے ساتھ استعمال ہونے پر، ایک غیر متوقع غلطی کی قدر کی نمائندگی کرتا ہے۔
template<typename...> ایک متغیر ٹیمپلیٹ کا خاکہ پیش کرتا ہے جس میں ٹیمپلیٹ دلائل کی لامحدود مقدار ہوتی ہے جسے وہ قبول کر سکتا ہے۔
decltype ٹیمپلیٹ پروگرامنگ میں استعمال کیا جاتا ہے، خاص طور پر اظہار کی قسم معلوم کرنے کے لیے۔
args.value() اگر کسی std::متوقع آبجیکٹ کی قدر ہو تو اس میں موجود قدر تک رسائی حاصل کرتا ہے۔
args.has_value() تصدیق کرتا ہے کہ آیا کوئی قدر std::متوقع آبجیکٹ میں موجود ہے۔
(... && args.has_value()) یہ تعین کرنے کے لیے کہ آیا ہر std::متوقع آبجیکٹ کی قدریں ہیں، اظہار کو فولڈ کریں۔
func(args.value()...) طریقہ فنک کو کال کرنے کے لیے std::متوقع آبجیکٹ کی قدروں کا استعمال کرتا ہے۔
return unexpected<Err>(args.error()...) std::متوقع آبجیکٹ کی خامیوں پر مشتمل ایک غیر متوقع خرابی لوٹاتا ہے۔

متغیر ٹیمپلیٹس کا استعمال کرتے ہوئے خرابی کا مؤثر انتظام

دی قسم کا استعمال اسکرپٹ میں C++23 میں غلطی سے نمٹنے کے لیے کیا جاتا ہے۔ بنیادی مقصد ایک عام فنکشن تیار کرنا ہے جسے کہا جاتا ہے۔ جو کئی کی پیداوار کو منتقل کر سکتا ہے۔ قدریں دوسرے فنکشن کے لیے۔ ایسا کرنے سے، تکلیف دہ غلطی کی جانچ پڑتال جو عام طور پر بہت سے لوگوں کے ساتھ کام کرتے وقت ضروری ہوتی ہے۔ std::expected اقدار کو کم کیا جاتا ہے. کافی لچکدار ہے کیونکہ یہ کسی بھی تعداد میں لے سکتا ہے۔ متغیر ٹیمپلیٹس کا استعمال کرتے ہوئے پیرامیٹرز۔ کسی کے مواد کے ساتھ فنکشن کو کال کرنے سے پہلے اعتراض، کی بنیادی منطق magic_apply فولڈ ایکسپریشن استعمال کرتا ہے، ، سب کو یقینی بنانے کے لئے اشیاء کی درست قدریں ہیں۔

اس خیال کو پہلی اسکرپٹ مثال میں سادہ اقسام کا استعمال کرتے ہوئے دکھایا گیا ہے جیسے اور . یہ وضاحت کرتا ہے a فنکشن جو ایک بنیادی حساب کتاب کرتا ہے، اور getA اور افعال جو واپس آتے ہیں۔ اقسام اگر دونوں اقدار سے اور getB جائز ہیں، ہم کال کر سکتے ہیں۔ استعمال کرتے ہوئے ; اگر نہیں، تو غلطی کی تشہیر کی جاتی ہے۔ بوائلر پلیٹ کوڈ کو کم کرکے، یہ طریقہ پڑھنے کی اہلیت اور برقرار رکھنے کی صلاحیت کو بڑھاتا ہے۔ اسی طرح کا خیال دوسری رسم الخط میں پیش کیا گیا ہے، لیکن نقطہ نظر کی استعداد کو اجاگر کرنے کے لیے، اقسام اور lambda functions استعمال کیا جاتا ہے.

`std::expected} کے ساتھ C++ ایرر ہینڈلنگ میں پیچیدگی کو کم کرنا

متغیر ٹیمپلیٹس کا استعمال کرتے ہوئے C++23 اسکرپٹ

#include <expected>
#include <string>
#include <iostream>
#include <tuple>

using namespace std;

template<typename Func, typename... Args, typename Err>
auto magic_apply(Func func, const expected<Args, Err>&... args) -> expected<decltype(func(args.value()...)), Err> {
    if ((... && args.has_value())) {
        return func(args.value()...);
    } else {
        return unexpected<Err>(args.error()...);
    }
}

expected<int, string> getA(int x) {
    if (x > 0) return x;
    return unexpected<string>("Error in getA");
}

expected<double, string> getB(double y) {
    if (y > 0) return y;
    return unexpected<string>("Error in getB");
}

double compute_all(int a, double b) {
    return a + b;
}

int main() {
    auto result = magic_apply(compute_all, getA(10), getB(20.5));
    if (result) {
        cout << "Result: " << result.value() << endl;
    } else {
        cout << "Error: " << result.error() << endl;
    }
    return 0;
}

مختلف {std::expected} کے نتائج C++23 اقدار کو یکجا کرنا

لیمبڈا فنکشنز کا استعمال کرتے ہوئے C++23 اسکرپٹ

#include <expected>
#include <string>
#include <iostream>

using namespace std;

template<typename Func, typename... Args, typename Err>
auto magic_apply(Func func, const expected<Args, Err>&... args) -> expected<decltype(func(args.value()...)), Err> {
    bool all_valid = (args.has_value() && ...);
    if (all_valid) {
        return func(args.value()...);
    } else {
        return unexpected<Err>(args.error()...);
    }
}

expected<string, string> getA(bool flag) {
    if (flag) return "SuccessA";
    return unexpected<string>("Failed A");
}

expected<string, string> getB(bool flag) {
    if (flag) return "SuccessB";
    return unexpected<string>("Failed B");
}

string compute_all(const string& a, const string& b) {
    return a + " and " + b;
}

int main() {
    auto result = magic_apply(compute_all, getA(true), getB(true));
    if (result) {
        cout << "Result: " << result.value() << endl;
    } else {
        cout << "Error: " << result.error() << endl;
    }
    return 0;
}

ویریڈک ٹیمپلیٹس کے ساتھ C++ ایرر ہینڈلنگ کو بہتر بنانا

کی صلاحیت پیچیدہ نظاموں میں خرابی سے نمٹنے کے لیے اسے C++ میں استعمال کرنے کا ایک اور اہم فائدہ ہے۔ بہت سے غیر مطابقت پذیر اعمال کے نتائج کو بغیر کسی رکاوٹ کے جوڑنا ان حالات میں ضروری ہے جب وہ حاصل کرتے ہیں۔ اقسام کوڈ کو آسان بنانے کے علاوہ، یہ طریقہ مضبوط غلطی سے نمٹنے کی ضمانت دیتا ہے۔ کی صوابدیدی تعداد کو ملا کر مزید ورسٹائل اور عام افعال بنائے جا سکتے ہیں۔ کے ساتھ اقدار variadic templates.

کی استعداد اسے ان فنکشنز کے ساتھ استعمال کرنے کی اجازت دیتا ہے جو مختلف قسم کے آرگومنٹ میں لیتے ہیں۔ استعمال کرکے عمل درآمد کو مزید آسان بنایا گیا ہے۔ ، جو مشترکہ فنکشن کال کی واپسی کی قسم کو خود بخود نکالتا ہے۔ مزید برآں، اس تکنیک کو مزید پیچیدہ کاموں کا انتظام کرنے کے لیے بڑھایا جا سکتا ہے، بشمول انضمام دیگر خرابی کی اقسام کے ساتھ اقدار یا انہیں فنکشن میں بھیجنے سے پہلے اقدار کو تبدیل کرنا۔ اس کی موافقت کی وجہ سے، پیٹرن کو کاموں کی ایک وسیع رینج کے لیے استعمال کیا جا سکتا ہے، سیدھے سادے حساب سے لے کر پیچیدہ آپریشنز تک۔

متغیر ٹیمپلیٹس اور std::expected کے بارے میں اکثر پوچھے گئے سوالات

  1. کیا ہے ?
  2. یہ ایک C++ ٹیمپلیٹ کی قسم ہے جو غلطی یا درست قدر رکھ سکتی ہے اور اسے ایرر مینجمنٹ کے لیے استعمال کیا جاتا ہے۔
  3. کیسے کرتا ہے کام
  4. یہ متعدد کے نتائج کو یکجا کرکے بار بار غلطی کی جانچ کی ضرورت کو ختم کرتا ہے۔ اقدار اور انہیں فنکشن میں منتقل کرنا۔
  5. متغیر ٹیمپلیٹس کیا ہیں؟
  6. متغیر ٹیمپلیٹس فنکشنز کو پیرامیٹرز کی صوابدیدی تعداد کو قبول کرنے کے قابل بنا کر فنکشن ڈیزائن میں بہت زیادہ آزادی پیش کرتے ہیں۔
  7. کیوں استعمال کریں۔ میں ?
  8. کی اقدار کا استعمال آبجیکٹ جو خود بخود اس فنکشن کی واپسی کی قسم کا تعین کرتی ہے جس کو بلایا جا رہا ہے۔
  9. ہے مختلف قسم کی غلطیوں کو سنبھالنے کے قابل؟
  10. ہاں، اس کے ساتھ کام کیا جا سکتا ہے۔ چند تبدیلیوں کے ساتھ مختلف قسم کی خرابی والی اقدار۔
  11. استعمال کرنے سے کیا فائدہ ہوتا ہے۔ پیشکش؟
  12. غلطیوں کو سنبھالتے وقت، یہ مستثنیات یا واپسی کوڈز جیسی روایتی تکنیکوں کے مقابلے میں زیادہ اظہار خیال اور صاف ستھرا طریقہ پیش کرتا ہے۔
  13. ہے کا حصہ ?
  14. اس کے علاوہ ، درحقیقت، ایک غلط قدر کی نمائندگی کرتا ہے۔
  15. کیا غیر مطابقت پذیر اعمال کے ساتھ استعمال کیا جا سکتا ہے؟ ?
  16. یہ واقعی ہینڈل کرنے کے قابل ہے غیر مطابقت پذیر کارروائیوں کے ذریعہ واپس کی گئی اقدار۔
  17. فولڈ ایکسپریشن کیا ہے؟
  18. یہاں، C++ میں جو فیچر فولڈ ایکسپریشن کہا جاتا ہے اس کو چیک کرنے کے لیے استعمال کیا جاتا ہے کہ آیا سب اشیاء سادہ انداز میں درست اقدار پر مشتمل ہیں۔

C++23 میں، ایک سے زیادہ std::متوقع اقدار کو ہینڈل کرنے کے لیے ایک عام فنکشن کو لاگو کرنا کوڈ کی پڑھنے کی اہلیت کو بہت بہتر بناتا ہے اور غلطی سے نمٹنے کو بہت آسان بناتا ہے۔ magic_apply فنکشن بوائلر پلیٹ کوڈ کو کم کرتا ہے اور مختلف ٹیمپلیٹس کا استعمال کرتے ہوئے برقرار رکھنے کی صلاحیت کو بڑھاتا ہے تاکہ یہ یقینی بنایا جا سکے کہ پروسیسنگ سے پہلے تمام متوقع اقدار درست ہیں۔ یہ طریقہ ایک لچکدار حل پیش کرتا ہے جو مختلف حالات پر لاگو کیا جا سکتا ہے اور جدید C++ پروگرامنگ کو ناکامیوں سے نمٹنے کے لیے ایک صاف ستھرا، زیادہ موثر طریقہ فراہم کرتا ہے۔