Menggunakan std::apply pada std::expected di C++23

C++

Menyederhanakan Penanganan Kesalahan di C++23

Menangani kesalahan secara efektif dan mengelola nilai kembalian sangat penting dalam pengembangan C++ saat ini. Metode umum bekerja dengan fungsi yang mengembalikan tipe {std::expected} mencakup banyak pemeriksaan dan kode penanganan kesalahan, yang dapat memperumit logika dan membuat kode lebih sulit dipelihara.

Makalah ini menyelidiki penggunaan metode yang lebih canggih dan umum untuk menyederhanakan manajemen kesalahan. Untuk mengurangi kode boilerplate dan meningkatkan keterbacaan, kita akan menyelidiki pembuatan metode `magic_apply` yang menggabungkan hasil dari banyak nilai {std::expected} dan meneruskannya ke fungsi lain.

Memerintah Keterangan
std::expected Tipe templat yang digunakan di C++ untuk penanganan kesalahan yang memiliki kemampuan untuk menyimpan nilai dan kesalahan.
std::unexpected Saat digunakan dengan std::expected, mewakili nilai kesalahan yang tidak terduga.
template<typename...> Menguraikan templat variadik dengan jumlah argumen templat tak terbatas yang dapat diterimanya.
decltype Digunakan dalam pemrograman template, terutama untuk mengetahui jenis ekspresi.
args.value() Jika objek std::expected memiliki nilai, akses nilai yang terkandung di dalamnya.
args.has_value() Memverifikasi apakah suatu nilai ada dalam objek std::expected.
(... && args.has_value()) Untuk menentukan apakah setiap objek std::expected memiliki nilai, lipat ekspresi.
func(args.value()...) Menggunakan nilai objek std::expected untuk memanggil fungsi metode.
return unexpected<Err>(args.error()...) Mengembalikan kesalahan tak terduga yang berisi kesalahan dari objek std::expected.

Manajemen Kesalahan yang Efektif Menggunakan Templat Variabel

Itu type digunakan dalam skrip untuk memudahkan penanganan kesalahan di C++23. Tujuan utamanya adalah untuk mengembangkan fungsi generik yang disebut yang dapat mengirimkan output beberapa nilai ke fungsi lain. Dengan melakukan ini, pemeriksaan kesalahan yang membosankan yang biasanya diperlukan saat bekerja dengan banyak orang std::expected nilainya berkurang. cukup fleksibel karena dapat memakan waktu berapa pun parameter dengan memanfaatkan templat variadik. Sebelum memanggil fungsi dengan isi apapun objek, logika dasar magic_apply menggunakan ekspresi lipatan, , untuk memastikan semuanya objek memiliki nilai yang valid.

Ide ini diilustrasikan dalam contoh skrip pertama menggunakan tipe sederhana seperti Dan . Ini mendefinisikan a fungsi yang melakukan komputasi dasar, dan getA Dan fungsi yang kembali jenis. Jika kedua nilai dari Dan getB sah, kita bisa menelepon menggunakan ; jika tidak, kesalahan akan disebarkan. Dengan mengurangi kode boilerplate, metode ini meningkatkan keterbacaan dan pemeliharaan. Gagasan serupa disajikan dalam naskah kedua, namun untuk menyoroti keserbagunaan pendekatan ini, jenis dan lambda functions digunakan.

Mengurangi Kompleksitas dalam Penanganan Kesalahan C++ dengan `std::expected}

Skrip C++23 Menggunakan Template Variadik

#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;
}

Menggabungkan nilai C++23 Hasil {std::expected} yang berbeda

Skrip C++23 Menggunakan Fungsi Lambda

#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;
}

Meningkatkan Penanganan Kesalahan C++ dengan Template Variadic

Kapasitas untuk meningkatkan penanganan kesalahan dalam sistem yang rumit adalah manfaat penting lainnya dari menggunakannya di C++. Menggabungkan hasil dari banyak tindakan asinkron secara mulus sangat penting dalam situasi ketika tindakan tersebut menghasilkan jenis. Selain menyederhanakan kode, metode ini menjamin penanganan kesalahan yang kuat. Fungsi yang lebih serbaguna dan umum dapat dibuat dengan menggabungkan sejumlah fungsi yang berubah-ubah nilai dengan variadic templates.

Fleksibilitas dari memungkinkannya untuk digunakan dengan fungsi yang menggunakan berbagai jenis argumen. Implementasinya semakin disederhanakan dengan memanfaatkan , yang secara otomatis menyimpulkan tipe kembalian dari pemanggilan fungsi gabungan. Selanjutnya, teknik ini dapat diperluas untuk mengelola tugas yang lebih rumit, termasuk penggabungan nilai dengan jenis kesalahan lain atau mengubah nilai sebelum mengirimkannya ke fungsi. Karena kemampuan beradaptasinya, pola ini dapat digunakan untuk berbagai tugas, mulai dari perhitungan sederhana hingga operasi kompleks.

Pertanyaan yang Sering Diajukan tentang Template Variadic dan std::expected

  1. Apa ?
  2. Ini adalah tipe templat C++ yang dapat menyimpan kesalahan atau nilai yang valid dan digunakan untuk manajemen kesalahan.
  3. Bagaimana caranya bekerja?
  4. Ini menghilangkan kebutuhan untuk pemeriksaan kesalahan berulang-ulang dengan menggabungkan banyak hasil nilai dan meneruskannya ke suatu fungsi.
  5. Apa itu template variadik?
  6. Templat variabel menawarkan banyak kebebasan dalam desain fungsi dengan memungkinkan fungsi menerima sejumlah parameter.
  7. Mengapa menggunakan di dalam ?
  8. Memanfaatkan nilai-nilai tersebut objek untuk secara otomatis menentukan tipe kembalian dari fungsi yang dipanggil.
  9. Adalah mampu menangani berbagai jenis kesalahan?
  10. Ya, itu bisa dibuat berfungsi nilai memiliki berbagai jenis kesalahan dengan beberapa penyesuaian.
  11. Apa keuntungan memanfaatkannya menawarkan?
  12. Saat menangani kesalahan, ini menawarkan pendekatan yang lebih ekspresif dan bersih dibandingkan dengan teknik yang lebih konvensional seperti pengecualian atau kode pengembalian.
  13. Adalah bagian dari ?
  14. Sebagai tambahan , sebenarnya mewakili nilai yang salah.
  15. Bisakah tindakan asinkron digunakan dengan ?
  16. Memang bisa beradaptasi untuk ditangani nilai yang dikembalikan oleh operasi asinkron.
  17. Apa itu ekspresi lipatan?
  18. Di sini, fitur di C++ yang disebut ekspresi lipat digunakan untuk memeriksa apakah semuanya objek berisi nilai yang valid dengan cara yang sederhana.

Di C++23, mengimplementasikan fungsi generik untuk menangani beberapa nilai std::expected sangat meningkatkan keterbacaan kode dan sangat menyederhanakan penanganan kesalahan. Fungsi magic_apply mengurangi kode boilerplate dan meningkatkan kemudahan pemeliharaan dengan menggunakan templat variadik untuk memastikan semua nilai yang diantisipasi sudah benar sebelum diproses. Metode ini menawarkan solusi fleksibel yang dapat diterapkan pada berbagai situasi dan memberikan pemrograman C++ modern cara yang lebih bersih dan efektif untuk menangani kegagalan.