Veakäsitluse sujuvamaks muutmine C++23-s
Vigade tõhus käsitlemine ja tagastusväärtuste haldamine on tänapäeva C++ arenduses hädavajalik. Tüüpiline töömeetod funktsioonidega, mis tagastavad tüüpi {std::expected}, sisaldab palju kontrolle ja veakäsitluse koodi, mis võib loogikat keerulisemaks muuta ja koodi hooldamist keerulisemaks muuta.
Selles artiklis uuritakse keerukama ja üldisema meetodi kasutamist vigade haldamise lihtsustamiseks. Katsekoodi vähendamiseks ja loetavuse parandamiseks uurime meetodi "magic_apply" loomist, mis koondab paljude {std::expected} väärtuste tulemused ja edastab need teisele funktsioonile.
Käsk | Kirjeldus |
---|---|
std::expected | Mallitüüp, mida kasutatakse C++-s vigade käsitlemiseks ja millel on võimalus salvestada nii väärtusi kui ka vigu. |
std::unexpected | Kui kasutatakse koos std::expected, tähistab ootamatu vea väärtus. |
template<typename...> | Joonistab varieeruva malli koos lõpmatu hulga malliargumentidega, mida see võib aktsepteerida. |
decltype | Kasutatakse mallide programmeerimisel, eriti avaldise tüübi väljaselgitamiseks. |
args.value() | Kui objektil std::expected on väärtus, pääseb see juurde selles sisalduvale väärtusele. |
args.has_value() | Kontrollib, kas std::expected objektis on väärtus. |
(... && args.has_value()) | Selleks et teha kindlaks, kas igal std::expected objektil on väärtused, voldi avaldis kokku. |
func(args.value()...) | Kasutab std::expected objektide väärtusi meetodi func kutsumiseks. |
return unexpected<Err>(args.error()...) | Tagastab ootamatu vea, mis sisaldab std::expected objektide vigu. |
Tõhus tõrkehaldus muutuvate mallide abil
The tüüpi kasutatakse skriptides, et hõlbustada C++23 vigade käsitlemist. Peamine eesmärk on välja töötada üldine funktsioon nimega mis suudab edastada mitme väljundi väärtused teisele funktsioonile. Seda tehes tüütu veakontroll, mis on tavaliselt paljudega töötamisel vajalik std::expected väärtused vähenevad. on üsna paindlik, sest selleks võib kuluda suvaline arv parameetrid, kasutades variadic malle. Enne funktsiooni kutsumist mis tahes sisuga objekt, põhiloogika magic_apply kasutab voltimisväljendit, , et kõik oleks kindel objektidel on kehtivad väärtused.
Seda ideed illustreerib esimene skripti näide, kasutades lihtsaid tüüpe, näiteks ja . See määratleb a funktsioon, mis teostab põhiarvutuse ja getA ja funktsioonid, mis tagastavad tüübid. Kui mõlemad väärtused alates ja getB on õigustatud, võime helistada kasutades ; kui ei, siis viga levib. Vähendades standardkoodi, suurendab see meetod loetavust ja hooldatavust. Sarnane idee on esitatud teises stsenaariumis, kuid et rõhutada lähenemisviisi mitmekülgsust, tüübid ja lambda functions kasutatakse.
C++ veakäsitluse keerukuse vähendamine käsuga `std::expected}
C++23 skript, kasutades variadic malle
#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;
}
Erinevate {std::expected} kombineerimine annab tulemuseks C++23 väärtused
Lambda funktsioone kasutav C++23 skript
#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++ veakäsitluse parandamine variadic mallidega
Võimsus vigade käsitlemise märkimisväärne tõhustamine keerulistes süsteemides on selle C++-s kasutamise teine oluline eelis. Paljude asünkroonsete toimingute tulemuste sujuv kombineerimine on oluline olukordades, kus need annavad tulemusi tüübid. Lisaks koodi lihtsustamisele tagab see meetod tugeva veakäsitluse. Mitmekülgsemaid ja üldisemaid funktsioone saab luua suvalise arvu funktsioonide kombineerimisel väärtused koos variadic templates.
Mitmekülgsus võimaldab seda kasutada funktsioonidega, mis võtavad vastu mitmesuguseid argumente. Rakendamist muudab veelgi lihtsamaks kasutamine , mis tuletab automaatselt välja kombineeritud funktsioonikutse tagastustüübi. Lisaks saab seda tehnikat laiendada keerukamate ülesannete haldamiseks, sealhulgas liitmiseks muud tüüpi veaga väärtused või väärtuste muutmine enne nende funktsioonile saatmist. Selle kohandatavuse tõttu saab mustrit kasutada paljude ülesannete jaoks, alates lihtsatest arvutustest kuni keerukate toiminguteni.
Korduma kippuvad küsimused variadic mallide ja std::expected kohta
- Mis on ?
- See on C++ mallitüüp, mis võib sisaldada viga või kehtivat väärtust ja mida kasutatakse vigade haldamiseks.
- Kuidas teeb töötada?
- See välistab vajaduse korduvate tõrkekontrollide järele, kombineerides mitmete tulemuste tulemusi väärtused ja nende edastamine funktsioonile.
- Mis on varieeruvad mallid?
- Muutuvad mallid pakuvad funktsioonide kujundamisel palju vabadust, võimaldades funktsioonidel aktsepteerida suvalise arvu parameetreid.
- Miks kasutada sisse ?
- Kasutades väärtusi objektid, et määrata automaatselt välja kutsutava funktsiooni tagastustüüp.
- Is suuteline käsitlema erinevaid veatüüpe?
- Jah, selle saab koos toimima panna väärtused, millel on mitmesugused veatüübid ja mõned näpunäited.
- Milliseid eeliseid annab selle kasutamine pakkuma?
- Vigade käsitlemisel pakub see väljendusrikkamat ja puhtamat lähenemist kui tavapärasemate tehnikatega, nagu erandid või tagastuskoodid.
- Is osa ?
- Lisaks sellele , esindab tegelikult vale väärtust.
- Kas asünkroonseid toiminguid saab kasutada koos ?
- See on tõepoolest kohandatav käsitsemiseks asünkroonsete operatsioonide poolt tagastatud väärtused.
- Mis on voltimisväljend?
- Siin kasutatakse C++ funktsiooni, mida nimetatakse voltimisväljenduseks, et kontrollida, kas kõik objektid sisaldavad kehtivaid väärtusi lihtsal viisil.
C++23-s parandab mitme std::oodatava väärtuse käsitlemise üldise funktsiooni rakendamine oluliselt koodi loetavust ja lihtsustab oluliselt vigade käsitlemist. Funktsioon magic_apply vähendab standardkoodi ja parandab hooldatavust, kasutades variadic malle, et enne töötlemist veenduda, et kõik eeldatavad väärtused on õiged. See meetod pakub paindlikku lahendust, mida saab rakendada erinevates olukordades ning annab kaasaegsele C++ programmeerimisele puhtama ja tõhusama viisi tõrgete käsitlemiseks.