BOOST_THROW_EXCEPTION在初始化列表中缺少三元运算符的变通方法

时间:2013-05-14 07:20:54

标签: c++ exception boost initialization-list

我经常最终使用三元组来抛出可能看起来有点奇怪的异常但是在初始化列表中保存一天(因此这有助于编写声音构造函数,因此这有助于RAII,...)。例如。如果参数a是我们想要非smart_ptr<>的{​​{1}},那么我可以发起像

这样的成员
nullptr

我认为这是一个有效的,合法的&amp;安全使用(如果不是这样,请告诉我。)

我最近切换到boost :: exception,遗憾的是member(a ? a->get_something() : throw exception()) 无法编译(因为编译器无法重新启用condition ? ret_value : BOOST_THROW_EXCEPTION(exception())typeof(ret_value))。

是否有任何解决方法比创建一个全新的私有静态方法并将void置于其中更好?

2 个答案:

答案 0 :(得分:0)

  

我认为这是一个有效的,合法的&amp;安全使用(如果不是这样,请告诉我。)

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

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

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

答案 1 :(得分:0)

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

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

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

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