3 ms·
It's easy to not write constructors that can fail. The major conveniences like templates, RAII, overloading, algorithms, lambdas, virtual functions, etc. work f
by edflsafoiewq 7y ago
It's easy to not write constructors that can fail. The major conveniences like templates, RAII, overloading, algorithms, lambdas, virtual functions, etc. work fine without exceptions.
- Koshkin 7y agoWhile the "major conveniences" are orthogonal to exceptions, constructors are not, and in many non-trivial cases constructors should be expected to fail.
- aidenn0 7y agoIt's doable to write constructors that don't throw exceptions; writing constructors that can't fail is not possible for a large fraction of the useful space of constructors. If your constructors fail without throwing an exception, much of the usefulness of RAII goes away.
- edflsafoiewq 7y agoThe traditional approach would be to have an empty state that the object can be put into, ie. classic two-step initialization. This isn't usually too hard since you often need an empty state you can put that kind of object into when it's moved from anyway. Another one is to have a private constructor called from a static function returning a std::expected<your_class, error>. How would that make the usefulness of RAII go away?
- aidenn0 7y agoThe whole point of RAII is that the scope of the variable is identical to the liveness of the resource. Two step initialization makes that no longer true.
- edflsafoiewq 7y agoThat's not quite right since (1) it's about object lifetime, not variable scope (think of the elements of a vector), and (2) the liveness of a resource is not generally identical to the lifetime of any object because of things like two-step initialization or moves. std::vector<int> v; // v's lifetime begins // currently owns nothing, exactly as in two-step initialization v = other_vector; // resource #1 becomes live v = std::move(another_vector); // resource #1 dies, resource #2 becomes live return std::move(v); // resource #2 now owned by returned object, will outlive v // v's lifetime ends I'd say RAII is more about making sure every resource always has an owner and that when an object dies, all the resources it owned are cleaned-up. And that works fine with two-step initialization.