在 C++ 中,
处理数学函数时都会用到定义域和范围误差。
一方面,函数的域是函数可以接受的值的集合。例如,平方根函数的域是正实数的集合。因此,当函数的参数不包含在其域中时,将抛出
domain_error
异常
另一方面,函数的范围是函数可以返回的值的集合。例如,像这样的函数的范围:
f(x) = -x²
是负实数的集合。那么
range_error
有什么意义呢?如果函数的参数在其定义域内,则结果必须在其范围内,因此我们不应该在范围方面出现任何错误...但是,有时该值可以是已定义,但不能可表示。例如,在 C 中,如果返回值的大小太大(或太小)而无法表示 ,则
<math.h>
中的函数会生成错误
域错误指的是函数的数学域的问题。有时仅为某些值定义函数。如果您尝试使用不属于其域的参数调用此类函数,则会出现域错误。
例如,尝试使用负参数调用
sqrt()
是一个域错误,因为负数不是 sqrt()
域的一部分。
非常好的解释表格cplusplus.com:
通常,数学函数的域是为其定义的值的子集。例如,平方根函数仅针对非负数定义。因此,此类函数的负数将是域错误。
嗯,这就是您从 C++ 标准获得的所有指导:
类domain_error定义了 作为异常抛出的对象类型 通过实施报告域 错误。
这里的域名是指“问题域名”,与互联网无关。例如,如果传递负数,平方根函数可能会引发域错误。
适用于“域”错误类的逻辑错误。这可能适用于函数输入超出其操作允许范围的任何情况。这就是标准中规定的目的。
例如,您有一个仅接受正浮点数的函数,因此它会针对负数抛出一个domain_error。
》详细说明 由库或您抛出,以报告域错误(数学意义上的域)。 ”
来自:http://www.aoc.nrao.edu/~tjuerges/ALMA/STL/html/classstd_1_1domain__error.html
根据此,如果您收到的输入不符合您对界面施加的约束,则应该使用它。就像说,一个函数应该接收一个正值,但被赋予一个负值。
它指的是数学领域。
float MySqrRoot(float x)
{
// sqrt is not valid for negative numbers.
if (x < 0) throw new domain_error;
//...
}
看来 std::domain_error 并没有被广泛使用。例如,微软表示,他们自己的 C++ 标准库实现没有任何函数,会引发此错误:https://learn.microsoft.com/en-us/cpp/standard-library/domain-error-类?视图=msvc-170
与
std::out_of_range
和 std::invalid_argument
一样,std::domain_error
继承自 std::logic_error
。因此 std::domain_error
应该用在程序逻辑被破坏的上下文中,但不应该在例如由于资源不可用而导致某些事情失败的情况下使用(例如 std::bad_alloc
,当内存已满时抛出,或者 std::ios_base::failure
,当文件无法打开、读取或写入并且已通过其 exceptions()
方法请求文件在这些条件下抛出时,会抛出该错误)。
《牛津词典》将“域”一词解释为:感兴趣的区域或一个人可以控制的区域。https://dictionary.cambridge.org/dictionary/english/domain
因此,例如,标准容器库的错误检查实现可能会在这里抛出
std::domain_error
,而不是仅仅以未定义的行为结束:
std::list<std::string> animals = { "Zebra", "Dog", "Rabbit" };
std::list<std::string> plants = { "Maple", "Wheat", "Rose" };
animals.erase(plants.begin());
这是一个域错误,因为迭代器
plants.begin()
超出了 animals
列表的控制范围。
但请记住,您不需要使用标准 C++ 库的异常,并且您可以定义自己的异常。