lundi 25 novembre 2019

rethrow_if_nested possible implementation

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, then E is derived from std::nested_exception and we can cast E* into std::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