3

derefernable 型に対して次のことを達成するにはどうすればよいですか?

動作させたいすべてのタイプに対してクラステンプレートの特殊化を行う必要があるため、現在のソリューションが不足していることがわかります。

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;
};

途中で何かを試しましたが、うまくいきません。

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;
4

2 に答える 2

7

std::pointer_traits<PointerType>::element_typeに住んでいる人を探しています<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.types]

typedef 以下を参照してください element_type

タイプ: Ptr::element_typeそのようなタイプが存在する場合。それ以外の場合、TPtrフォームのクラス テンプレートのインスタンス化である場合SomePointer<T, Args>Argsは 0 個以上の型引数です。それ以外の場合、特殊化は不適切な形式です。

ああ、ポインタ型にも特殊化があります。

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;
};
于 2012-01-02T00:39:32.307 に答える
2

広すぎる可能性のある解決策の 1 つは、テンプレート テンプレート引数を使用することです。

template <template <typename> class C, typename T>
struct get_value_type<C<T>>
{
    typedef T value_type;
};

より柔軟なソリューションでは、バリアディックを使用します。

template <typename> struct get_first_param;

template <template <typename...> class C, typename T, typename ...Args>
struct get_first_param<C<T, Args...>>
{
    typedef T value_type;
};
于 2012-01-02T00:19:50.140 に答える