What is the best way to throw exception from the constructor initializer?
For example:
class C {
T0 t0; // can be either valid or invalid, but does not throw directly
T1 t1; // heavy object, do not construct if t0 is invalid, by throwing before
C(int n)
: t0(n), // throw exception if t0(n) is not valid
t1() {}
};
I thought maybe making wrapper, e.g. t0(throw_if_invalid(n))
.
What is the practice to handle such cases?
Just wrap class T0 inside another class which does throw in cases like this:
This is a way to throw from the initializer list
You're saying "throw exception if t0(n) is not valid". Why don't you throw from the constructor of T0?
An object is supposed to be valid after construction.
You can
throw
from the expression(s) that initializet0
ort1
, or any constructor that takes at least one argument.Note that a
throw
expression hasvoid
type, makingthrow
more like an operator than a statement. The?:
operator has a special case to prevent thatvoid
from interfering with its type deduction.There are multiple ways of going about this, I think. From what I understand,
n
can only take on a specific range of numbers. For that, you might prevent the constructor from even being run:Could be more fleshed out, but that's the idea. Now you can clamp the range:
If you pass a value that does not lie from 0-100, the above would throw.
At runtime, I think your original idea was best:
And that's it. Same as above, but 0 and 100 can be replaced with a call to some function that returns the valid minimum and maximum.
If you do end up using a function call to get valid ranges (recommended, to keep clutter to a minimum and organization higher), I'd add an overload:
To allow stuff like this:
If I were to choose, I'd pick the runtime methods even if the range was compile-time. Even with low optimization the compiler will generate the same code, and it's much less clumsy and arguably cleaner to read than the class version.