2016-03-25 9 views
1

Say, üye olan çeşitli türleri, TypeMathcer için uzmanlaşmış bir şablon var.İsteğe bağlı bağımlı türdeki şablon konusunda uzmanlaşmak için nasıl

#include <memory> 
#include <vector> 

template <typename T> 
struct TypeMatcher; 

template <typename T> 
struct TypeMatcher<T *> 
{ 
    // making some type from T 
    typedef std::shared_ptr<T> type; 
}; 

template <typename T> 
struct TypeMatcher<T&> 
{ 
    // making other type from T 
    typedef std::vector<T> type; 
}; 

Şimdi, başka bir şablon oluşturmak ve ben TypeMatcher aldığım türleri için bunu uzmanlaşmak istiyorum. Bu

template <typename T> 
struct MyNeedfullTemplate; 

template <typename T> 
struct MyNeedfullTemplate<typename TypeMatcher<T>::type> 
{  
}; 

gibi, basit yaparsanız ben derleyici hatası alıyorum: template parameters not deducible in partial specialization.

aynı hata varsa kullanım

template <typename T> 
using type_matcher_t = typename TypeMatcher<T>::type; 

template <typename T> 
struct MyNeedfullTemplate; 

template <typename T> 
struct MyNeedfullTemplate<type_matcher_t<T> > 
{ 
}; 

Cevabın bir karşı örnek mevcut tüm soru anlamsız yaparsa emin değilim hala soruma çok benzer partial specialization for iterator type of a specified container type ama sorgulamaya okumak using sözdizimi. Ayrıca şimdi durumu değiştirebilecek yepyeni C++ 14 ve C++ 17 standartlarımız var. Öyleyse eğer uzmanlıkların benzersiz ve var olduğundan emin olursam, parametrelerin çıkarılabilir hale getirilmesinden başka bir olasılık var mıdır?

cevap

2

Prensip olarak bu imkansızdır ve C++ 9999 hiçbir fantezi bunu değiştiremez.

kodunda bir kullanım gibi MyNeedfulTemplate<int> vardır: Tek yapmanız derleyici soruyorsun ne

. Derleyici, U = int için MyNeedfulTemplate<U> tanımına gereksinim duyar. bunlardan herhangi biri varsa sen

template <typename T> 
struct MyNeedfullTemplate<typename TypeMatcher<T>::type> 

bu uzmanlık uygular olup olmadığını görmek için formun kısmi uzmanlaşma sağlamaya çalışıyoruz, derleyici tüm olası T siçin TypeMatcher<T> incelemek ve bulmak zorunda kalacak type iç içe geçmiş bir yazım hatası int. Bu "tüm olası T s" sonsuz olduğu için bu olamaz. Tamam, TypeMatcher<int> böyle bir tür yok ve ne TypeMatcher<int*> ne de TypeMatcher<int**>, ne de TypeMatcher<int***>. Peki ya TypeMatcher<int****> ne yapar? Denemeye devam et…

Ayrıca, kısmi ve eksiksiz uzmanlaşmanın var olduğunu unutmayın, yani TypeMatcher'un kendisi uzman olabilir.

Kısacası, sahip tüm int değil X ise bir TypeMatcher<X>::type bir int bağlantı kuracak bir yolu yoktur.


Sen yeniden yapılanma tarafından benzer bir şey elde etmek mümkün olmalıdır TypeMatcher biraz() tersini:

template <class T> 
struct TypeMatcher2 
{ 
    static constexpr specialised = false; 
}; 

template <class T> 
struct TypeMatcher2<std::shared_ptr<T>> 
{ 
    static constexpr specialised = true; 
    using OldType = T*; 
}; 

template <class T> 
struct TypeMatcher2<std::vector<T>> 
{ 
    static constexpr specialised = true; 
    using OldType = T&; 
} 

template <class T, bool spec = TypeMatcher2<T>::specialised> 
struct MyNeedfullTemplate 
{ 
    // generic version 
}; 

template <class T> 
struct MyNeedfullTemplate<T, true> 
{ 
    using OriginalT = typename TypeMatcher2<T>::OldType; 

    // specialised version 
}; 
+0

Tamam, anlıyorum. Ancak bu tür bir şablonun yerini alacak herhangi bir ortak model var mı?Özellikleri ya da bilmediğim başka şey gibi bir şey. – user2807083

+0

@ user2807083 Potansiyel bir çözüm ekledim (kullanım durumunuzu doğru anladığımı varsayarak). – Angew

+0

Oh, öyle. Bazı çözümlerin olduğundan şüpheleniyorum. – user2807083

1

Ben ne yapmaya çalışıyoruz bu olduğunu düşünüyorum:

#include <iostream> 

#include <memory> 
#include <vector> 
#include <utility> 

template <typename T> 
struct TypeMatcher; 

template <typename T> 
struct TypeMatcher<T *> 
{ 
    // making some type from T 
    typedef std::shared_ptr<T> type; 
}; 

template <typename T> 
struct TypeMatcher<T&> 
{ 
    // making other type from T 
    typedef std::vector<T> type; 
}; 


template <typename T, typename = void> 
struct MyNeedfullTemplate; 

template <typename T> 
struct MyNeedfullTemplate<TypeMatcher<T>, std::enable_if_t<std::is_same<typename TypeMatcher<T>::type, std::vector<std::remove_reference_t<T>>>::value>> 
{ 
    static void report() { std::cout << "hello" << std::endl; } 
}; 
int main() 
{ 
    using matcher_type = TypeMatcher<int&>; 
    using full_type = MyNeedfullTemplate<matcher_type>; 
    full_type::report(); 

    return 0; 
} 

Soruyu doğru anlıyor muyum?

+0

Neredeyse, ancak her tür için ayrı bir uzmanlık yazmayı kastetmiyorum, 'TypeMatcher' ile eşleşti, çünkü threre bu türden sonsuz dizidir. – user2807083

+0

Bir TipMatcher türünün nasıl yorumlanacağını daha önce yorumlamak gerektiğini anladım. –

+0

Ben bence aşırı örneklendim. Benim temel sorun varadic şablon ve tip listeleri ile oldu, ben ayrı tip listeleri olarak tek ve çift türleri ayıklamak ve her tip çifti için 'std :: is_convertible' uygulamak yerine deneyin. Bu konuda daha fazla düşünmem gerekiyor ve belki bir gün doğru soruyu sorabilirim. Hala ihtiyacım olan şeyleri formüle edemem. – user2807083

İlgili konular