2015-10-24 21 views
5

İki türün aynı olup olmadığını, ancak şablon parametrelerinden bağımsız olarak kontrol etmek isterim. Böyle bir şey:İki türün aynı tempold sınıfından gelip gelmediğini kontrol etme

template<class T> 
class A {}; 
class B {}; 

int main() { 
    cout << std::is_same_template<A<int>, A<string>>::value << endl; // true 
    cout << std::is_same_template<A<int>, B>::value << endl; // false 
} 

Ben iki tip exacty eşleşirse kontrol için std::is_same farkındayım.

Bunu neden ihtiyaç A nedeni: Ben herhangi bir türü ile çağrılabilir templated yöntemi var ama bir static_assert kullanarak muhtemelen ki (şablon olarak değiştirilebilir) tip A ile adı verilir yasaklamak istiyorum. El ile birkaç ortak Ts için hariç tutabilir kullanarak, bir arıyorum: A şablonlu muyduk

DÜZENLEME ..., ben std::is_same kullanarak kolayca yapılabilir inanıyorum, ama şimdi, bir sorun var yolu tüm T için bunu yapmak için:

static_assert(!std::is_same<parameter_type, A<int>>::value, "Cannot use this function with type A<T>"); 
static_assert(!std::is_same<parameter_type, A<double>>::value, "Cannot use this function with type A<T>"); 
static_assert(!std::is_same<parameter_type, A<bool>>::value, "Cannot use this function with type A<T>"); 
+0

İki tip: Aşağıdaki açıklama, uzmanlaşma std::array için (veya aynı imzaya sahip diğer şablonda) 'de @Helix tarafından talep edildiği üzere şablon parametreleri farklıysa, aynı değildir. Böylece, "" ve "A ", aynı tür olmaktan uzaktır. – skypjack

+2

Eh, bunun farkındayım, bu yüzden std :: is_same' kullanamıyorum. Ne soruyorum, daha az karşılaştırma yapmak için bir yol varsa, A ve A eşit ve A ve B değil mi? – jureslak

+0

Tersine çevirilmiş yaklaşımı şablon uzmanlığı ile kullanabilirsiniz, böylece yalnızca izin verilen sınıfları kabul edin ve boş/kırık/atma/başka türlü bir işlevi tanımlayın. – skypjack

cevap

4

Tamam, bu nasıl: Şu anda bir project of mine kullanılan @ NikitaKakuev cevabı, daha basit bir şekilde geldim

#include <iostream> 

template<class T> 
struct A {}; 
struct B {}; 

template <typename T> 
struct should_reject { static constexpr bool value = false; }; 

template <typename T> 
struct should_reject<A<T>> { static constexpr bool value = true; }; 

template <typename T> 
void rejectA(T t) 
{ 
    std::cout << should_reject<T>::value << std::endl; 
} 

int main() { 
    rejectA(B());   // false 
    rejectA(1);   // false 
    rejectA(1.0);   // false 
    rejectA(A<B>());  // true 
    rejectA(A<int>()); // true 
    rejectA(A<double>()); // true 
} 
+0

İçinde bulunduğunuz iki kişiyi eşit olarak karşılaştırmak istiyorum, ama bana bazı fikirler verdiniz. Tanımlanmış bir sınıfa sahip olan türleri reddetmek için işlevini değiştirebilir miyim? Ya da belki bir çalışma zamanı değeri ... (ve downvote benim değil) – jureslak

+0

Oh, sorunuzu tamamen yanlış okuyorum. Bunun için özür dilerim. –

+0

Cevabımı düzenledim. –

3

.

template<typename, typename> 
constexpr bool is_same_template{false}; 

template< 
    template<typename...> class T, //typename T in C++17 
    typename... A, 
    typename... B 
> 
constexpr bool is_same_template< 
    T<A...>, 
    T<B...> 
>{true}; 

Tek geçerli sorun, türleri ve yazım adlarını karıştıran şablonlarla ilgilidir, örn. std::array<int, 10>.
Bu sınırlamanın üstesinden gelmek için uzmanlaşma gereklidir.

Kullanımı:

bool b = is_same_template<std::string, std::wstring>; //true 
//both are typedefs of std::basic_string 

DÜZENLEME:

template< 
    template<typename, std::size_t> class T, //typename T in C++17 
    typename TA, std::size_t NA, 
    typename TB, std::size_t NB 
> 
constexpr bool is_same_template< 
    T<TA, NA>, 
    T<TB, NB> 
>{true}; 
+0

Hey, cevabınızı, bu uzmanlık örneğini içerecek şekilde güncelleyip güncelleyemeyeceğinizi merak ediyordum. – FrogTheFrog

+1

@Helix işte gidiyorsunuz. – bit2shift

İlgili konular