bmaxa
Legenda
- Poruka
- 70.808
Trend je uveliko da se error hendling zameni sa tagovanim unijama, pa ja vec neko vreme
ne koristim exceptione u C++, nego sam napisao klasu koja mimikuje Rustov Result<T,E>.
Koristi se vrlo jednostavno, samo treba proveriti sa li je isOk pa dobiti resultat a ko je isErr handlovati gresku.
znaci result_t func();
auto rc = func();
if (rc.isErr()){ cerr<< rc.Err() <<std::endl(); }
i u samoj f-ji make_ok i make_err.
Ovaj trend je poceo sa Rust, a ideja je iz funckionalnog programiranja gde se koristi ovaj nacin (Haskell Either i Maybe tipovi).
I tako. Postoji i predlog od Herb Sutter-a da se C++ exceptioni implementiraju na ovaj nacin.
Pomenuti Zig ima u sam jezik ugradjen ovaj mehanizam koliko autor smatra da je ispravno.
ne koristim exceptione u C++, nego sam napisao klasu koja mimikuje Rustov Result<T,E>.
C++:
#include <string>
namespace MyNamespace {
template <class T>
struct Ok {
T val;
};
template <class T>
struct Err {
T val;
};
template <class V> Ok<V> make_ok(V v) {
Ok<V> rc;
rc.val = v;
return rc;
}
template <class V> Err<V> make_err(V v) {
Err<V> rc;
rc.val = v;
return rc;
}
template <class O, class E>
struct Result {
enum {OK,ERR} tag;
union {
O ok;
E err;
};
Result(const Err<E>& err):tag(ERR),err(err.val) {
}
Result(const Ok<O>& ok):tag(OK),ok(ok.val) {
}
Result(const Result& in) {
tag = in.tag;
switch (tag) {
case OK: *new(&ok)O() = in.ok;
break;
case ERR: *new(&err)E() = in.err;
break;
}
}
Result& operator=(const Result& in) {
if (this == &in)return *this;
this->~Result();
tag = in.tag;
switch (tag) {
case OK: *new(&ok)O() = in.ok;
break;
case ERR: *new(&err)E() = in.err;
break;
}
return *this;
}
~Result() {
if (tag == ERR) { err.~E(); }
else { ok.~O(); }
}
bool isOk()const { return tag == OK; }
bool isErr()const { return tag == ERR; }
O& Ok() { return ok; }
E& Err() { return err; }
};
typedef Result<int, std::string> result_t;
extern const result_t rc0;
}
Koristi se vrlo jednostavno, samo treba proveriti sa li je isOk pa dobiti resultat a ko je isErr handlovati gresku.
znaci result_t func();
auto rc = func();
if (rc.isErr()){ cerr<< rc.Err() <<std::endl(); }
i u samoj f-ji make_ok i make_err.
Ovaj trend je poceo sa Rust, a ideja je iz funckionalnog programiranja gde se koristi ovaj nacin (Haskell Either i Maybe tipovi).
I tako. Postoji i predlog od Herb Sutter-a da se C++ exceptioni implementiraju na ovaj nacin.
Pomenuti Zig ima u sam jezik ugradjen ovaj mehanizam koliko autor smatra da je ispravno.
Poslednja izmena od moderatora: