rethrow_if_nested 可能的实施
rethrow_if_nested possible implementation
cppreference.com 提供了一些关于 rethrow_if_nested
可能实现的细节。我对这些细节很感兴趣。虽然大多数表达式对我来说似乎都是合理的,但 can_dynamic_cast
的定义有点令人困惑:
template <class E>
struct can_dynamic_cast
: std::integral_constant<bool,
std::is_polymorphic<E>::value &&
(!std::is_base_of<std::nested_exception, E>::value ||
std::is_convertible<E*, std::nested_exception*>::value)
> { };
我无法想象 (!std::is_base_of<std::nested_exception, E>::value || std::is_convertible<E*, std::nested_exception*>::value)
编译时求值结果为 false
的情况。更具体地说,
- 如果
std::is_base_of<std::nested_exception, E>::value == false
,那么
!std::is_base_of<std::nested_exception, E>::value == true
- 如果
std::is_base_of<std::nested_exception, E>::value == true
,那么
类型 E
派生自 std::nested_exception
并且我们可以将 E*
转换为 std::nested_exception*
无论如何。
所以,问题是我的讨论有什么问题,为什么can_dynamic_cast
要这样实施?
注意:据我所知,GCC 7 实现了上述逻辑。同时,LLVM 的实现似乎是检查参数的类型是多态的,没有别的:
template <class _Ep>
inline _LIBCPP_INLINE_VISIBILITY
void
rethrow_if_nested(const _Ep& __e, typename enable_if<
is_polymorphic<_Ep>::value
>::type* = 0)
当 std::nested_exception
是 E
的不明确或不可访问的基础(例如 E
私下继承自 std::nested_exception
)时,std::is_base_of<std::nested_exception, E>::value
为真,但 E*
不能转换为 std::nested_exception*
.
cppreference.com 提供了一些关于 rethrow_if_nested
可能实现的细节。我对这些细节很感兴趣。虽然大多数表达式对我来说似乎都是合理的,但 can_dynamic_cast
的定义有点令人困惑:
template <class E>
struct can_dynamic_cast
: std::integral_constant<bool,
std::is_polymorphic<E>::value &&
(!std::is_base_of<std::nested_exception, E>::value ||
std::is_convertible<E*, std::nested_exception*>::value)
> { };
我无法想象 (!std::is_base_of<std::nested_exception, E>::value || std::is_convertible<E*, std::nested_exception*>::value)
编译时求值结果为 false
的情况。更具体地说,
- 如果
std::is_base_of<std::nested_exception, E>::value == false
,那么!std::is_base_of<std::nested_exception, E>::value == true
- 如果
std::is_base_of<std::nested_exception, E>::value == true
,那么 类型E
派生自std::nested_exception
并且我们可以将E*
转换为std::nested_exception*
无论如何。
所以,问题是我的讨论有什么问题,为什么can_dynamic_cast
要这样实施?
注意:据我所知,GCC 7 实现了上述逻辑。同时,LLVM 的实现似乎是检查参数的类型是多态的,没有别的:
template <class _Ep>
inline _LIBCPP_INLINE_VISIBILITY
void
rethrow_if_nested(const _Ep& __e, typename enable_if<
is_polymorphic<_Ep>::value
>::type* = 0)
当 std::nested_exception
是 E
的不明确或不可访问的基础(例如 E
私下继承自 std::nested_exception
)时,std::is_base_of<std::nested_exception, E>::value
为真,但 E*
不能转换为 std::nested_exception*
.