2

我经常最终使用抛出异常的三元组,这可能看起来有点奇怪,但在初始化列表中节省了一天(因此有助于编写合理的构造函数,因此有助于 RAII,...)。例如,如果参数asmart_ptr<>我们想要的 non nullptr,那么我可以发起一个类似的成员

member(a ? a->get_something() : throw exception())

我认为这是一种有效、合法和安全的使用方式(如果不是这样,请告诉我)。

我最近切换到 boost::exception,不幸condition ? ret_value : BOOST_THROW_EXCEPTION(exception())的是没有编译(因为编译器无法 reify typeof(ret_value)and void)。

有没有比创建一个全新的私有静态方法并放入if内部更好的解决方法?

4

2 回答 2

0

我认为这是一种有效、合法和安全的使用方式(如果不是这样,请告诉我)。

不是,imo。你不能也不应该为你可能得到的任何蹩脚的论点辩护。因为如果您愿意,您将不得不检查所有内容。如果size_t函数参数包含合理的值,则必须对其进行检查。如果它是否为 NULL,则必须检查任何char*内容,如果不是,则必须检查它是否以零分隔。您必须在整个类和函数中应用数千次检查,以检查不太可能发生但在某些奇怪情况下可能发生的事情。

考虑std::strlenand std::string::string(char const*):两者都要求参数是指向以空字符结尾的字符字符串的非空指针。没有应用检查,如果你通过 NULL,你会得到 UB。

在许多情况下,函数保证返回非空指针。如果将这样的结果传递给您的构造函数(或者strlen,就此而言),那么额外的检查就是浪费时间和编程工作。
简而言之:不要测试空指针,而只是要求非空指针。传递正确的参数是客户端的责任,因为只有客户端代码知道是否有必要检查空指针,并且无论如何它必须通过在调用之前检查或通过捕获异常来处理空指针的情况。

于 2013-05-14T08:04:39.613 回答
0

这是完全有效的 C++,但许多编译器不会将 BOOST_THROW_EXCEPTION 视为一个抛出表达式,而只是一个常规的 void 类型表达式。由于标准要求 void 类型表达式是 throw 表达式,或者两个分支都是 void 类型,因此编译器拒绝三元表达式。

典型的解决方法是使用逗号运算符:

condition ? ret_value : (BOOST_THROW_EXCEPTION(exception()), decltype(ret_value){})

当然,您可以将逗号后面的部分替换为任何正确类型的表达式,并且您可以确定它不会被使用。

于 2017-11-22T14:38:16.267 回答