2016-05-13 12 views
7

İlke tabanlı sınıf tasarımı için variadic parametre paketlerini kullanıyorum.Şablon Sınıfı için Çoklu Değişken Parametre Paketi

Çağrılar, çağrılmadıklarında veya hiçbiri belirtilmediyse varsayılanlarla tanımlanır.

Bu "son şablon parametresi olmalıdır Şablon parametre paketi" hata ile sonuçlanır
template <AttributeType... Attributes, APITypes APIType, class... Policies> 
class IShader : public Policies... { 

}; 

: Başka variadic parametre paketi eklemeniz gerekir sorunu geliyor. Politikalardan en az birinin davranışını değiştirmek için özellik paketini kullanmayı planlıyorum. Ancak, bir şablon sınıfında iki değişkenli parametre paketinin nasıl alınacağını anlayamıyorum.

+1

Yapamazsınız. Şablonunuzu/sınıf tasarımınızı yeniden düşünmeniz gerekiyor. –

+1

Bir çeşit dolaylılıkla bile değil misiniz? Özellik listesi için bir tür sarıcı söyleyin. Ya da şablon şablonları? – James

+6

Her zaman IShader , APIType, İlkeler > – chris

cevap

5

Tartışma yorumlarında, bir tür dolaylı veya "öznitelik listesi için bir çeşit sarıcı" düşünmeye istekli olduğunu belirtmiştiniz.

hafif std::tuple tabanlı sarıcı birlikte uzmanlaşma ile burada çalışabilir:

template <typename attribute_tuple, APITypes APIType, 
      typename policy_tuple> class IShader; 

template <AttributeType... Attributes, APITypes APIType, 
      class... Policies> 
class IShader<std::tuple<Attributes...>, APIType, 
       std::tuple<Policies...>> : public Policies... { 

// ... 

}; 

Buradaki amaç çizgisinde bir şablon örneği kullanmaktır:

IShared<std::tuple<Attribute1, Attribute2>, APITypeFoo, 
     std::tuple<Policy1, Policy2>> ishared_instance; 

Ve çapraz senin Bu, özel şablon bildirimi ile eşleşecek parmaklardır; bu noktada, her iki parametre paketi de, şablon uzmanlığı için tek tek kullanım için kullanılabilir.

+0

IShader sınıfının nesneleri bildirirken gerekli tuples musunuz? – James

+0

@James Tuplelere ihtiyaç vardır, ancak sadece bir tür. Hiçbir tuple gerçeklenmemiş. – md5i

+0

Burada bile 'IShared , APITypeFoo, std :: tuple > ishared_instance;'? Daha sonra uygulamayı sağlayan uzmanlığı kullanmaz, varsayılanı değil. Bu 'IShared <özellik1, Attribute2, APITypeFoo, Policy1, Policy2> ishared_instance gibi sınıf kullanılamadı;'? – James

6

En basit yanıt, parametre paketleriniz için şablon türü sarmalayıcılar oluşturmaktır. Örneğin:

template <typename... T> 
class IShader; 

bir uzmanlık olarak uygulanmasını oluşturun:

template <AttributeType... T> 
struct Attributes {}; 

template <typename... T> 
struct Policies {}; 

Sonra IShader tür bildirebilirsiniz. Bir uzmanlıkta, birden fazla parametre paketi argümanına sahip olabileceğinizi unutmayın.

template <AttributeType... AttributeList, ApiTypes APIType, typename... PolicyList> 
struct IShader<ApiType, Policies<PolicyList...>, Attributes<AttributeList...> 
    : public IShader<Attributes<AttributeList...>, ApiType, Policies<PolicyList...>> 
{ 
    using IShader<Attributes<AttributeList...>, ApiType, Policies<PolicyList...>>::IShader; 
}; 

Gerçekten olmanın ediyorsanız:

template <AttributeType... AttributeList, ApiTypes APIType, typename... PolicyList> 
class IShader<Attributes<AttributeList...>, ApiType, Policies<PolicyList...>> 
    : public PolicyList... 
{ 
    ... 
}; 

Sonra hatta kullanıcı farklı sıralarda argümanları belirtmek (o miras yoluyla bu şekilde yapıyor eğer kurucular iletmek emin olun) izin verebilir fantezi, tüm siparişleri numaralandırmadan herhangi bir sıradaki argümanlara izin vermek için meta programlama hileleri bile kullanabilirsiniz. Bu okuyucuya bir egzersiz olarak bırakılır. :)