2016-04-09 27 views
0

Aşağıdaki kod parçacığını dikkate alınız anlaşılabilir değildir:benim kısmi şablon uzmanlık şablon parametresi

template<class E> 
class vector_expression {}; 

template<class Tuple> 
class vector 
    : public vector_expression<vector<Tuple>> 
{ 
public: 
    using value_type = typename Tuple::value_type; 
}; 

template<typename T> 
using dynamic_vector = vector<std::vector<T>>; 

namespace detail 
{ 
    template<class E> 
    constexpr bool is_vector_expression_v = std::is_base_of_v<vector_expression<std::decay_t<E>>, std::decay_t<E>>; 

    template<class E> 
    struct value_type { using type = std::decay_t<E>; }; 
    template<class E> 
    struct value_type<vector_expression<std::decay_t<E>>> { using type = typename std::decay_t<E>::value_type; }; 
    template<class E> 
    using value_type_t = typename value_type<E>::type; 
} 


int main() 
{ 
    static_assert(std::is_same<detail::value_type_t<dynamic_vector<double>>, double>::value, "not the same"); 
    return 0; 
} 

Ben E bir vector_expression olduğunda E belirtilen value_type olmak value_type_t<E> istiyorum. Yukarıdaki kod çalışmıyor, E şablon parametresinin value_type kısmi uzmanlaşmasında sonuçlanamaz. Kodu nasıl çalıştırabilirim? aslında std::decay<E>::type olduğu gibi

DEMO

+0

Gibi [burada] (http://coliru.stacked-crooked.com/a/35a7e10935ac63a0)? –

cevap

2

std::decay_t<E> (ve aslında, E birkaç özel durumda aynı tip yol açabilir) deducible değildir.

İkinci düzeltme senin static_assert geçmek gereklidir: dynamic_vector<double> gibi

değil vector_expression ama ondan devralan, senin uzmanlık uymuyor. Bunu düzeltmek için SFINAE kullanabilir:

template<class E, typename Enabler = void> 
struct value_type { using type = std::decay_t<E>; }; 

template<class E> 
struct value_type<E, std::enable_if_t<is_vector_expression_v<E>>> { 
    using type = typename std::decay_t<typename E::type>::value_type; 
}; 

Demo

1

ilk sorun kısmi uzmanlaşma olmayan deducible olmasıdır. Yani sadece std::decay_t bırak, daha kolay bir Çözüm şudur:

template<class E> 
struct value_type<vector_expression<E>> { using type = typename E::value_type; }; 

Ancak şimdi bu bunu yapmak istediğinizi yapmaz ki daha büyük bir problem var. dynamic_vector<double>, E için vector_expression<E> değildir. Bu , numaralı telefondan öğelerini devralır, ancak bu, bu eşleşmenin amaçlarına yardımcı olmayacaktır. Yani yukarıdaki düzeltme derlenecek, ancak yine de birincil şablonla eşleşiyorsunuz - size yanlış value_type veriyor.

Muhtemelen istediğin, value_type yazım hatası konusunda uzmanlaşmaktır. Bu şu anda static_assert .

İlgili konular