从构造函数初始值设定项抛出异常
从构造函数初始值设定项抛出异常的最佳方法是什么?
例如:
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() {}
};
我想也许可以制作包装器,例如t0(throw_if_invalid(n))
。
处理此类案件的做法是什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是从初始化列表中抛出的一种方法
您说“如果 t0(n) 无效则抛出异常”。
为什么不从 T0 的构造函数中抛出?
一个对象在构造后应该是有效的。
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.
只需将类 T0 包装在另一个类中,在这样的情况下确实会抛出:
Just wrap class T0 inside another class which does throw in cases like this:
您可以从初始化
t0
或t1
的表达式或任何至少采用一个参数的构造函数中抛出
。请注意,
throw
表达式具有void
类型,这使得throw
更像是一个运算符而不是语句。?:
运算符有一个特殊情况,可以防止void
干扰其类型推导。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.我认为有多种方法可以解决这个问题。据我了解,
n
只能采用特定范围的数字。为此,您甚至可以阻止构造函数运行:可以更充实,但这就是想法。现在你可以限制范围:
如果你传递的值不在 0-100 之间,上面的代码就会抛出异常。
在运行时,我认为你最初的想法是最好的:
就是这样。与上面相同,但 0 和 100 可以替换为调用某个返回有效最小值和最大值的函数。
如果您最终确实使用函数调用来获取有效范围(推荐,以将混乱降至最低并提高组织水平),我会添加一个重载:
允许这样的内容:
如果我要选择,我会选择运行时方法,即使范围是编译时的。即使优化程度较低,编译器也会生成相同的代码,而且它比类版本更不笨拙,而且可以说更容易阅读。
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.