2013-07-30 14 views
5

Sabit bir değere sahip olduğumu varsayalım (muhtemelen bazı enum türlerinde). Diyelim ki pek çok sınıf A, B, D, vb. Var.Derleme süresinde, muhtemelen şablonlar kullanarak bir sınıf seçmek için sabit bir sayı kullanabilir miyim?

Böyle bir şeye sahip olabilir miyim?

C<1> anInstanceOfA; //This will be of type A 
C<2> anInstanceOfB; //This will be of type B 
C<3> anInstanceOfD; //This will be of type D 

Yani, derleme zamanında bir sabit sayısına dayanarak bir sınıf seçmek mümkün mü?

Genel sorun, dizinin bir numara olduğu bir tabloyu temel alarak bir functor seçmeye çalışıyorum. Mümkünse polimorfizmden kaçınmak istiyorum.

Düzenleme: C++ 11 kullanamazsınız Bu proje için, yine bu bağlamda cevap kim sayesinde çok ilginç zaten bilmek.
Düzenleme 2:

template <int N> 
struct C { 
    typedef typename std::conditional<N == 1,A,B>::type type; 
}; 

Sen C<1>::type foo; olarak bulur: Ben 2'den fazla hedef sınıfları olabilir Genel olarak, Sorumu

+0

Belki de "fabrika kalıbı" nı okuyun – arne

cevap

8

: C++ tatmin kamu miras IS-Bir kural yana

template <int N> class C; 
template <> class C<1> : public A {}; 
template <> class C<2> : public B {}; 
template <> class C<3> : public D {}; 

C<1> anInstanceOfA; 

, anInstanceOfA hem C<1> nesne A-IS ve IS_AN A nesne.

+0

örneğinde kaydeder. Farklı bir dil konuşuyorsunuz :) ama gerçekten bu çözüm çok şık! Kullanımım için birkaç bağlantı: http://en.wikipedia.org/wiki/Liskov_substitution_principle ... ve IS-A ile ilgili bir şey bulamıyorum ... – Antonio

+0

Derlemeyi eklemek için eklemek istediğim '{} ' , "template <> class C <1> elde ediliyor: public A {};' ... Doğru mu? – Antonio

+0

@Antonio evet bu doğru. – 0x499602D2

4

Bu oldukça basit bir üst-işlevin olduğunu düzenledim.

sizin derleyici C++ 11 şablon adlar destekliyorsa

, sen kolaylaştırabilirsiniz için:

template <int N> 
using C = typename std::conditional<N == 1,A,B>::type; 

ve tercih C<1> foo; sözdizimi vardır. Saf C++ 03 yılında

olarak std::conditional uygulamak:

template <bool, typename A, typename> 
struct conditional { 
    typedef A type; 
}; 

template <typename A, typename B> 
struct conditional<false, A, B> { 
    typedef B type; 
}; 
+0

Hatta yer kazanmak için std :: koşullu 'yu yerleştirebilirsiniz. Yazılan her bir yazmayı ayrı ayrı yazmanın okunabilirliği üzerine yorum yapmayacağım. – rubenvb

+0

Üzgünüm, ben belirtmeliydim (şimdi var), C++ kullanamıyorum 11 – Antonio

+2

@Antonio: 'std :: conditional' tam olarak yazmak zor değil, aklınız var, ya da herhangi bir C++ uygulamasına dayanıyor 11 özellik. – Fanael

11

Bu Bunu yapmanın tek yolu değildir, ama senin amaçlar için kabul edilebilir umut:

struct A { }; 
struct B { }; 

template <int N> 
struct choices; 

template <> 
struct choices<1> { typedef A type; }; 

template <> 
struct choices<2> { typedef B type; }; 

template <int N> 
using C = typename choices<N>::type; 

Güncelleştirme: C++ 11 özellikleri olmadan aynısını yapmak için, typedef üye türünü aşağıdaki karşılık gelen tür diğer adlara eşit olan C bir sınıf yapmalısınız:

LSP'yi ve düz C++ 98 Kullanma
template <int N> 
struct C 
{ 
    typedef typename choices<N>::type type; 
}; 

// ... 
C<1>::type anInstanceOfA; 
C<2>::type anInstanceOfB 
+0

Teşekkürler! (+1 elbette) Sonunda MSalters cevabını daha kompakt olarak seçeceğim ve çünkü – Antonio

İlgili konular