cppreference.com provides some details on rethrow_if_nested possible implementation. These details are of interest to me. While most of the expressions seem reasonable to me, the definition of can_dynamic_cast is a little bit confusing:
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)
> { };
I can't imagine a situation where (!std::is_base_of<std::nested_exception, E>::value || std::is_convertible<E*, std::nested_exception*>::value) evaluation at compile time results into false. To be more specific,
- if
std::is_base_of<std::nested_exception, E>::value == false, then!std::is_base_of<std::nested_exception, E>::value == true - if
std::is_base_of<std::nested_exception, E>::value == then, thenEis derived fromstd::nested_exceptionand we can castE*intostd::nested_exception*anyway.
So, the question is what is wrong with my discussion, and why can_dynamic_cast shall be implemented this way?
NB: As far as I can see, GCC 7 implements the logic above. At the same time, LLVM's implementation seems to check that the type of the argument is polymorphic, and nothing else:
template <class _Ep>
inline _LIBCPP_INLINE_VISIBILITY
void
rethrow_if_nested(const _Ep& __e, typename enable_if<
is_polymorphic<_Ep>::value
>::type* = 0)
Aucun commentaire:
Enregistrer un commentaire