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
, thenE
is derived fromstd::nested_exception
and 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