Pro mě je C++ moc složité, chybí tam důležité funkce a naopak tam jsou zbytečnosti.
Například preferuji používat vlastní alokátory před RAII, preferuji mechanizmy chyb ze Zigu nebo C3, případně Result z Rustu, před výjimkami (abych věděl, co může skončit chybou, případně jakou). A preferuji compile-time reflexi (jako má třeba Zig nebo C3) před šablonami v C++ (něco takového chtějí přidat i do C++, ale v jiných jazycích už to je).
Naopak nepotřebuji dědičnost, RAII, virutální funkce a šablony mi stačí jen místo generik.
Tak já RAII používám dost masivně, ani si nedokážu představit, že bych to psal jinak. Třeba že když opustím objekt transakce, tak se mi sama commitne, nebo když opustím zámek, tak se mi zámek odemkne... atd...
Co se Result vs výjimky - nevím no, vždycky si člověk řekne, tady výjimky nepoužiju a pak skončí tím, že všechno vrací chybu a všechno musím ošetřovat. Rustovsky "když error tak return error" (aka ?), je už skoro jak výjimkový systém, akorát se o tom nesmí mluvit.
U těch výjimek/chyb mi přijde důležité, zda vím, jaký kód je vyhazuje a jaký ne. Případně i jaké výjimky. Občas je dokonce fajn vědět, zda může nastat chyba, protože došla paměť.
> Třeba že když opustím objekt transakce, tak se mi sama commitne, nebo když opustím zámek, tak se mi zámek odemkne
Občas se to hodí. Ale třeba u transakcí si radši sám určím, zda se má rollbacknout nebo commitnout, a nevadí mi to mít explicitně v kódu.
U těch transakcí jsem to měl tak, že jsem musel explicitně označit transakci za úspěšnou, aby se v destruktoru commitla, jinak byl rollback. Ještě "línější" řešení je, když destruktor transakce se dívá, jestli neletí výjimka. Pokud letí, udělá rollback, jinak commit. Ale s tímhle řešením si nejsem jist. Vždycky ale ten objekt transakce má možnost manuální řízení (jako unique_lock)
Jak říkám u ošetření chyb - ze všeho může vypadnout chyba.
A pak tady máš chyby které spíš nenastanou. Například mám program, co komunikuje s externí službou přes JSON. Šance, že by ze služby vypadl nevalidní JSON je prakticky nulová. Takže vůbec tuhle situaci neošetřuju, netestuju. No ale přesto se tam hodí mít try - catch na nějaké základní úrovni, která pořeší i výjimku s nevalidním JSONem.
C++ rozhodně s C kompatibilní není. Co hůře některé stejně vypadající konstrukty a klíčová slova majíí v C a C++ zcela jiný význam (např. inline ... v C znamená že se má funkce inlinovat, v cpp to znamená že ji definujete jako slabý symbol pro linkování a má být deduplikována, nebo třeba typická zrada, kdy "string" je v C char* ale v cpp const char*).
No, zcela jiný význam...
Inline v C taky "jen" umožňuje inlinování tím, že řeší konflikty symbolů při linkování. Jen to dělá malinko jinak. Takže v C je třeba udělat trochu víc práce, aby se úspěšně slinkoval i debug build. Tam i tam to pak překladače můžou interpretovat i jako hint, že se to zainlinovat má.
V C jsou sice string literály char *, ale zápis je nedefinované chování. Takže to člověk do toho const char * chce přiřadit už jenom proto, aby si náhodou nenaběhl na vidle.