Recursively dereference pointer

前端 未结 2 483
再見小時候
再見小時候 2021-01-15 19:42

While trying to answer one question here, I found this question:

How to recursively dereference pointer (C++03)?

Adapted code from the answer is following:

相关标签:
2条回答
  • 2021-01-15 19:52

    You can do it with a trait to compute the ultimate return type, here dubbed remove_all_pointers:

    #include <type_traits>
    
    template <typename T> struct remove_all_pointers
    { typedef typename std::remove_reference<T>::type type; };
    template <typename T> struct remove_all_pointers<T *>
    { typedef typename std::remove_reference<T>::type type; };
    
    template <typename T>
    T & dereference(T & p)
    { return p; }
    
    template <typename U>
    typename remove_all_pointers<U>::type & dereference(U * p)
    { return dereference(*p); }
    
    int main(int argc, char * argv[])
    {
      return dereference(argv);
    }
    

    You may need to add CV-variants; I'm still thinking about that.

    0 讨论(0)
  • 2021-01-15 20:13

    This is possible with the use of a custom can_dereference trait:

    template <typename T>
    struct can_dereference_helper {
        template <typename U, typename = decltype(*std::declval<U>())>
        static std::true_type test(U);
        template <typename...U>
        static std::false_type test(U...);
        using type = decltype(test(std::declval<T>()));
    };
    
    template <typename T>
    struct can_dereference :
      can_dereference_helper<typename std::decay<T>::type>::type {};
    

    and some mutually-recursive functions with a bit'o tag dispatching:

    template <typename T>
    auto recursive_dereference(T&& t, std::false_type) ->
      decltype(std::forward<T>(t)) {
        return std::forward<T>(t);
    }
    
    template <typename T>
    auto recursive_dereference(T&& t) ->
      decltype(recursive_dereference(std::forward<T>(t), can_dereference<T>{}));
    
    template <typename T>
    auto recursive_dereference(T&& t, std::true_type) ->
      decltype(recursive_dereference(*std::forward<T>(t))) {
        return recursive_dereference(*std::forward<T>(t));
    }
    
    template <typename T>
    auto recursive_dereference(T&& t) ->
      decltype(recursive_dereference(std::forward<T>(t), can_dereference<T>{})) {
        return recursive_dereference(std::forward<T>(t), can_dereference<T>{});
    }
    

    See it work live at Coliru. This may seem like overkill compared to Kerrek's answer, but I went for a generic approach that will dereference anything that supports operator*. I'll let you decide which tool fits your problem best.

    0 讨论(0)
提交回复
热议问题