2013-05-02 26 views
10

Bütün sabah bu sorun üzerinde hiç bir sonuç olmadan yaşadım. Temel olarak, eğer parametre geçtiyse bir tür std :: vector olsun ya da olmasın, farklı uzmanlıklara dalmamı sağlayan basit bir meta programlama işine ihtiyacım var.Bir tür std :: vektörün uzmanlığı olup olmadığını nasıl öğrenebilirim?

Şablonlar için bir çeşit is_base_of.

Böyle bir şey var mı?

+0

"Uzmanlık" ile miras anlamına mı geliyor? Veya bir tür takma ad (ör. "Typedef")? Veya belirli bir tür için özel bir uygulama (std :: vector 'gibi)? –

+1

Sorunuz belirsiz: Eğer türün bir türü için std :: vector 'şablon uzmanlığı olup olmadığını belirlemek istiyorsanız, bunu yapamamanız gerekir (yine de temiz bir şekilde değil). Bir türün std :: vector 'dan miras alınıp alınmadığını belirlemek istiyorsanız, bu durum açıkça karşılanır (std :: vektörünün sanal bir yıkıcıya sahip olmaması ve devralınması GEREKMEZ, yalnızca kapsüllenmiş olması gerekir). Bir class/typedef/template parametresinin bir std :: vector olup olmadığını belirlemek isterseniz, şablonlanmış bir özellik sınıfı kullanmalısınız (jrok'un cevabına bakın). – utnapistim

+0

@utnapistim: Bir türün genel olarak bir şablon uzmanlığı olup olmadığını kontrol etmek * zor değildir. –

cevap

12

: Bir özellik sınıfı gerekiyorsa

+0

Vay, çok tatlı kardeşim! – Michael

+0

Merhaba! Bu örnek, tip olmayan bir şablon parametresi olan std :: array'i de desteklemek için nasıl değiştirilebilir? –

+0

Hayır, sanmıyorum. Bunun nedeni, bir typename veya bir değer türü olan ve bir tip veya somut bir değeri tutabilen jenerik bir mekanizmanın olmamasıdır. Üzgünüz, sanırım özel bir is_std_array şablonu yazmalısın. – Databyte

3

Hayır, ancak yalnızca std::vector<T> kabul eden bir şablon işleviyle aşırı yüklenebilirsiniz. Derleyici bu gibi durumlarda en özel şablonu seçecektir. Ayrıca daha genel bir şekilde yapabiliriz C++ 11 yılında

#include <type_traits> 
#include <iostream> 

template<typename> 
struct is_std_vector : std::false_type {}; 

template<typename T, typename A> 
struct is_std_vector<std::vector<T,A>> : std::true_type {}; 

int main() 
{ 
    typedef std::vector<int> vec; 
    typedef int not_vec; 
    std::cout << is_std_vector<vec>::value << is_std_vector<not_vec>::value; 
} 
15

o, sadece genel bir şablon ve bir ihtisas herhangi std::vector üzerinde oldukça basittir ihtiyaç var:

#include <type_traits> 
#include <iostream> 

template<typename Test, template<typename...> class Ref> 
struct is_specialization : std::false_type {}; 

template<template<typename...> class Ref, typename... Args> 
struct is_specialization<Ref<Args...>, Ref>: std::true_type {}; 


int main() 
{ 
    typedef std::vector<int> vec; 
    typedef int not_vec; 
    std::cout << is_specialization<vec, std::vector>::value << is_specialization<not_vec, std::vector>::value; 

    typedef std::list<int> lst; 
    typedef int not_lst; 
    std::cout << is_specialization<lst, std::list>::value << is_specialization<not_lst, std::list>::value; 
} 
+5

Tam olmak için, aslında vektörleri özel ayırıcılar ile yakalamak için 'vektör ' için uzmanlaşmalısınız. – dhavenith

+0

@dhavenith kesinlikle doğru, işaret ettiğin için teşekkürler. – jrok

+1

Ayrıca not: uygulamaların fazladan şablon argümanları eklemesine izin verilir, böylece kontrol etmek isteyebilirsiniz. Yukarıdaki kod, olası ek şablon parametreleri için varsayılan değerleri kullanan her vektör örneğini algılayacaktır. –

İlgili konular