I how would I achieve the following for any derefernable type?
I find my current solution lacking since I need to do a class template specialization for every type I want it to work with:
template<typename T>
struct get_value_type
{
    typedef typename T::value_type value_type;
};
template<typename E>
struct get_value_type<std::unique_ptr<E>>
{
    typedef typename E::value_type value_type;
};  
template<typename E>
struct get_value_type<std::shared_ptr<E>>
{
    typedef typename E::value_type value_type;
};  
template<typename E>
struct get_value_type<boost::optional<E>>
{
    typedef typename E::value_type value_type;
};
I've tried the something along the ways of, which doesn't work.
template<typename T, typename IsIndirect = false_type>
get_value_type
{
    typedef typename T::value_type value_type;     
}
template<typename T>
struct get_value_type<T, true_type>
{
     typedef decltype(*boost::declval<E>())::value_type value_type; 
};
typedef get_value_type<T, is_indirect<T>::type> value_type;
                You're looking for std::pointer_traits<PointerType>::element_type which lives in <memory>.
#include <memory>
#include <boost/optional.hpp>
template <class Ptr>
struct MyPointer
{
};
template <class Ptr>
struct YourPointer
{
    typedef signed char element_type;
};
int main()
{
    static_assert
    (
        std::is_same
        <
            std::pointer_traits<std::unique_ptr<double>>::element_type,
            double
        >::value,
        ""
    );
    static_assert
    (
        std::is_same
        <
            std::pointer_traits<std::unique_ptr<short[]>>::element_type,
            short
        >::value,
        ""
    );
    static_assert
    (
        std::is_same
        <
            std::pointer_traits<std::shared_ptr<const char>>::element_type,
            const char
        >::value,
        ""
    );
    static_assert
    (
        std::is_same
        <
            std::pointer_traits<boost::optional<int*>>::element_type,
            int*
        >::value,
        ""
    );
    static_assert
    (
        std::is_same
        <
            std::pointer_traits<MyPointer<long long>>::element_type,
            long long
        >::value,
        ""
    );
    static_assert
    (
        std::is_same
        <
            std::pointer_traits<YourPointer<long long>>::element_type,
            signed char
        >::value,
        ""
    );
}
20.6.3.1 Pointer traits member types [pointer.traits.types]
typedefsee belowelement_type;Type:
Ptr::element_typeif such a type exists; otherwise,TifPtris a class template instantiation of the formSomePointer<T, Args>, whereArgsis zero or more type arguments; otherwise, the specialization is ill-formed.
Oh, and there's a specialization for pointer types as well:
template <class T>
struct pointer_traits<T*>
{
    typedef T*        pointer;
    typedef T         element_type;
    typedef ptrdiff_t difference_type;
    template <class U> using rebind = U*;
    static pointer pointer_to(see below r) noexcept;
};
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With