mercredi 26 avril 2017

Can somebody explain this code?

1.  template <typename Base> std::true_type is_base_of_test_func( Base* );
2.  template <typename Base> std::false_type is_base_of_test_func( void* );
3.  template <typename Base, typename Derived>
    using pre_is_base_of = decltype( is_base_of_test_func<Base>( std::declval<Derived*>() ) );

4.  template <typename Base, typename Derived, typename = void>
    struct pre_is_base_of2 : public std::true_type {};

5.  template<typename ...> using void_t = void;
6.  template <typename Base, typename Derived>
    struct pre_is_base_of2<Base, Derived, void_t<pre_is_base_of<Base, Derived>>> : public pre_is_base_of<Base, Derived>{};


7.  template <typename Base, typename Derived>
    struct is_base_of : public std::conditional_t<std::is_class<Base>::value && std::is_class<Derived>::value,
                                                  pre_is_base_of2<Base, Derived>,
                                                  std::false_type>
    {
    };

Lines 1. and 2. are pretty much straight forward. But, line 3: the using there is extremely vague, because I cannot simply replace every occurrence of pre_is_base_of with its definition. Ergo, the using is not really what the documentation says. It involves some religion as well. If I'm not wrong, the usage of pre_is_base_of should return std::true_type or std::false_type.
I'm equally lost when it comes to void_t. What kind of magic will that line do?
Shouldn't both implementations of pre_is_base_of2 take 3 types? What's the point of inheritance in line 6? There is probably more, but lets stop now.

I would need some detailed explanation on magic involved here. Basically I'm trying to understand how that code works.

Aucun commentaire:

Enregistrer un commentaire