"Doctor it hurts when I do this." Well stop doing that then. Learn what works and what doesn't, but don't throw the baby out with the bathwater.
"Doctor it hurts when I do this." Well stop doing that then. Learn what works and what doesn't, but don't throw the baby out with the bathwater.
And you can do things like enforce that the return value is used by checking in the destructor if the return value was unwrapped.
Similarly for constructors if you have an object that can fail construction instead of doing what the author suggested of
class foo {
public:
foo ();
int init ();
...
};
You could instead do something better like: class foo {
private:
foo ();
int init ();
...
public:
static std::optional<std::unique_ptr<Foo>> create();
};
This is a well-established pattern in languages like Java, for example, to do exactly what the author wants - a constructor that can fail without forcing callers to just know they need to try/catch.If C idioms work better in your project, just go for C. You get other advantages from that, like faster compile times and being independent from C++ stdlib, which can be messy at times (not even speaking about Boost). You don't have to stay with C++ just because somebody else (or even you) thinks that it's generally a better language.
Similarly while exceptions are part of the Java idioms, it does after all have checked exceptions even, it's incredibly common to not use that idiom on constructors, where it's weird. Just because a thing is an idiom in some cases doesn't mean it's the expected idiom in ALL cases.
And if an idiom is dumb it doesn't mean you should just do it to follow along with the dumb, nor should you go to a language where you're forced to be less safe & less clear just because "but mah idioms". Be the change you want to see.
1: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p070... has the survey data (along with a language proposal to make return-value exceptions a proper C++ feature)
typedef struct
{
int err;
int value;
} rtn_t;
rtn_t rtn = foo();
if(rtn.err < 0)
printf( "err=%i", rtn.err);
else
printf( "value = %i\n", rtn.value);But only one of them would make sense at a given moment, so why waste memory?
By comparison some something like https://github.com/oktal/result will tell you if it's a success or error without any magic error codes that actually mean success.
You could do this with a type bit + union in C, it's just more painful without templates
In c it'll be either in a register or on the stack.
A seasoned dev that thinks errno and longjump are good idea's should have retired 25 years ago.
Similarly I'd probably substitute the optional with a variant that has the actual error code. Go nuts with whatever you want here.
Let's make error code optional, too.
Then again, many C++ younger devs don't even know what Booch method might be all about.
Just because they may be overused in Java doesn't mean people shouldn't use them at all in other languages.
Besides arguments about portability, C's only "advantage" vs C++ is a lack of features. This isn't an advantage for a serious engineering project, or really any project with code review.
And of course, things like RAII are incredibly useful when managing resources, and templates for encapsulating generic data-structure behavior in an operating system.
https://fuchsia.googlesource.com/zircon/+/master/kernel/incl... https://fuchsia.googlesource.com/zircon/+/master/kernel/kern...
Even things like SpinLock, which I was expecting to use class for RAII, looks like it was implemented using C, then with a C++ wrapper: https://fuchsia.googlesource.com/zircon/+/master/kernel/incl...
So to me (I'm no C/C++/Kernel/etc. expert) it looks like they are writing the kernel mostly in C, with C++ goodies sprinkled in some places, where it's useful (ie: RAII for spinlock guard)
I could do with just generics. I am honestly sold on the idea that OOP is flawed. I've tried to do "real" projects in C, but the continuous casting just felt like unnecessary ceremony.
Sorry, Linus didn't say anything compelling against C++. He explained very clearly why C++ didn't fit with his own personal way to work, and that's fair.But his message did never contain anything more than this!
At one point hacking around these issues become a bigger cost than just using some C library
Though personally I think the abstraction ceiling on C is so low I can’t imagine that cost ever being that high, other people are more comfortable with macro-based APIs
Yes, you need to be aware of object lifetimes in c++, but so do you in C. C++ makes it far easier to manage, though.
std::vector<T> x_Vec;
if (!(x_Vec.find(another_x) == std::vector<T>::npos) {
//some code
}
Also the ugly std::get<N> syntax.. auto x = std::get<0>(myTuple);
Why not - auto x = myTuple.0 if (x_Vec.find(another_x) != x_Vec.end()) {
//some code
}
The reason why vector doesn't have contains() is because it would be an O(N) operation for a vector. STL is generally designed in such a way that, when something needs to do an O(N) lookup, it has to deal with iterators, making the iteration happening in the background a bit more explicit.But, for example, for std::set and map, you can just do:
if (a_set.count(x)) { ... }
It's not a good pattern for multiset and multimap, since it won't stop at the first occurrence. C++20 finally added contains() for that reason - but, again, only to associative containers. if (find(x, v.begin(), v.end()) != v.end()) ...
For maps and sets, find is a member function though. Same principle - if it is implemented in some optimized way, the class provides it directly, but not otherwise.A surprising amount of pain comes from cargo-culting/copy-pasting some behaviour because the "old way sucks" and the "new way rocks" (the opposite problem also happens, that it being stuck in old ways, or: "how do I lift this excavator? I want to dig" )