初始化列表中缺少BOOST_THROW_EXCEPTION三元运算符的解决方法
workarounds for BOOST_THROW_EXCEPTION's missing ternary operator in initialization lists
我经常使用抛出异常的三元格式,这可能看起来有点奇怪,但在初始化列表中节省了时间(因此有助于编写声音构造函数,因此有助于RAII,…)。例如,如果参数a
是我们想要的非nullptr
的smart_ptr<>
,那么我可以初始化一个成员,如
member(a ? a->get_something() : throw exception())
我认为这是一个有效的,合法的&安全使用(如果不安全请告诉我)。
我最近切换到boost::exception,不幸的是condition ? ret_value : BOOST_THROW_EXCEPTION(exception())
不编译(因为编译器不能具体化typeof(ret_value)
和void
)。
有没有比创建一个全新的私有静态方法并在里面放一个if
更好的解决方案?
这在c++中是完全有效的,但是许多编译器不会将BOOST_THROW_EXCEPTION视为throw表达式,而只是普通的void类型表达式。由于标准要求void类型表达式要么是throw表达式,要么两个分支都是void类型,编译器拒绝三元表达式。
典型的解决方法是使用逗号操作符:condition ? ret_value : (BOOST_THROW_EXCEPTION(exception()), decltype(ret_value){})
当然,您可以用任何正确类型的表达式替换逗号后面的部分,并且可以确定它不会被使用。
我认为这是一个有效的,合法的&安全使用(如果不安全请告诉我)。
在我看来并非如此。你不能也不应该为任何蹩脚的论点辩护。因为如果要这样做,就必须检查所有内容。任何size_t
函数参数都必须检查它是否包含一个合理的值。任何char*
都必须检查它是否为NULL,如果不是,则必须检查它是否为零分隔。你必须在你的类和函数中应用成千上万的检查,以检查不太可能发生但在某些奇怪的情况下可能发生的事情。
考虑std::strlen
和std::string::string(char const*)
:它们都要求实参是指向以空结尾的字符串的非空指针。没有应用检查,如果传递NULL,则得到UB。
strlen
),那么额外的检查就是浪费时间和编程精力。简而言之:不要测试空指针,而只要求非空指针。传递正确的参数是客户端的责任,因为只有客户端代码知道是否需要检查空指针,并且无论如何都必须处理空指针的情况,要么在调用前检查,要么捕获异常。
- 三元运算符和 if constexpr
- 在 c++ 中三元运算符中不允许继续(关键字)吗?
- 三元运算符在返回语句中给出意外的结果
- 递归中三元运算符的奇怪行为
- 错误:三元运算符无法在对象中正常工作"cout"
- 是否允许三元运算符在C++中计算两个操作数?
- 有条件地选择带有 decltype() 和三元运算符的类型
- 三元运算符在C++中的意外行为
- 有没有办法将 for 循环结果返回到像三元运算符这样的函数中?
- 变量值,在三元运算符之后
- 是否可以在C++中使用三元运算符在 if 语句中选择比较运算符?
- c++中的增量和三元运算符优先级
- C++中三元运算符的意外行为
- 用于返回开关的三元运算符
- 替换模板元编程中的三元运算符
- 三元运算符 '?:' 在 4.9.0 之前的 GCC 版本中推断出不正确的类型?
- 在 std::map 上使用三元运算符和 std::更大的附加参数
- "Do nothing"在三元运算符的其他部分?
- 如何确定三元运算符的返回类型?
- 无法使用三元运算符有条件地分配"istream &"?