2013-04-04 13 views
6

nasıl şablon argümanları tekrarlamadan (ve makro kullanmadan) bir şablon temel sınıfından Kurucular miras yok: ÖrneğinŞablon bağımsız değişkenlerini tekrar etmeden şablon taban sınıfındaki kurucuları mi saklıyorsunuz?

, bu (GCC 4.8 kullanarak) çalışmaz:

template <typename T> 
struct base {}; 

template <typename U> 
struct derived : base<U> { 
    using base::base; 
}; 

It does Ben temel sınıf şablon argümanları tekrar çalışmayabilir:

template <typename T> 
struct base {}; 

template <typename U> 
struct derived : base<U> { 
    using base<U>::base; 
}; 

sorun "u" çok karmaşık bir şey olabilir ve bu can sıkıcı ve hata tekrarlamak eğilimli olmasıdır.

#define MAKE_UNIQUE_LIST(template_params...)\ 
template <typename T>\ 
struct unique_list : multi_index_container template_params\ 
{\ 
    using multi_index_container template_params ::multi_index_container;\ 
    using as_list = as_list_tag;\ 
    using as_set = as_set_tag ;\ 
}; 

MAKE_UNIQUE_LIST(< 
    T, 
    indexed_by < 
     sequenced<tag<as_list_tag>>, 
     ordered_unique<tag<as_set_tag>, identity<T>> 
    > 
>) 
#undef MAKE_UNIQUE_LIST 

bu yaklaşım daha iyi bir yolu var mı:

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/key_extractors.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/sequenced_index.hpp> 

using namespace boost::multi_index; 

struct as_list_tag {}; 
struct as_set_tag {}; 

template <typename T> 
struct unique_list : multi_index_container < 
    T, 
    indexed_by < 
     sequenced<tag<as_list_tag>>, 
     ordered_unique<tag<as_set_tag>, identity<T>> 
    > 
> { 
    using multi_index_container < 
     T, 
     indexed_by < 
      sequenced<tag<as_list_tag>>, 
      ordered_unique<tag<as_set_tag>, identity<T>> 
     > 
    > 
    ::multi_index_container; 
    using as_list = as_list_tag; 
    using as_set = as_set_tag ; 
}; 

Ben makro kullanarak bu sorunu çalışma sona erdi: Örneğin, burada benim orijinal motive örneklerinden biridir? Bazı sözdizimi numarası eksik mi? =)

+0

'typedef base parent;' –

+0

@MooingDuck Yine de en az iki kez yinelemeniz gerekir (bir kez ve türetmek için '' 'yapıcıları devralmak için ''. – Zereges

cevap

3

Mükemmel değil, ama senin tipini üreten bir sınıf olabilir:

template <typename T> 
struct unique_list_base { 
    typedef multi_index_container < 
     T, 
     indexed_by < 
      sequenced<tag<as_list_tag>>, 
      ordered_unique<tag<as_set_tag>, identity<T>> 
     > 
    > type; 
}; 

template <typename T> 
struct unique_list : unique_list_base<T>::type { 
    using unique_list_base<T>::type::multi_index_container; 
    using as_list = as_list_tag; 
    using as_set = as_set_tag ; 
}; 
+0

unique_list_base önce typename hakkında :: type GCC diyor ki: "Bu bağlamda 'typename' anahtar sözcüğü izin verilmiyor (temel sınıf bir tür örtüktür)" – wjl

+0

Ekstra yazım adını kaldırdıktan ve kendimi karıştırdığım yazım hatası yazdıktan sonra, Bu işi yapabiliyordum. Teşekkürler! – wjl

+4

@wjl Unique_list_base = multi_index_container <...>; 'kullanarak şablon 'u kullanarak daha da basitleştirebilirsiniz. –

2

o tam bir cevap yapmak için rahatsız etmedi çünkü Sadece Daniel Frey çözümünü vurgulamak için: şablonu beyanı kullanarak (aka şablon typedef) gitmek için yoldur.

template <typename T> 
using unique_list_base = 
    multi_index_container < 
     T, 
     indexed_by < 
      sequenced<tag<as_list_tag>>, 
      ordered_unique<tag<as_set_tag>, identity<T>> 
     > 
    >; 

template <typename T> 
struct unique_list : unique_list_base<T> { 
    using unique_list_base<T>::multi_index_container; 
    using as_list = as_list_tag; 
    using as_set = as_set_tag ; 
}; 

Bu şekilde, struct kurtulmak ve yaygın C++ 03 foobar<T>::type deyim ile kullanıldı tüm ilişkili Demirbaş alabilirsiniz.

+0

Güzel. Son zamanlarda 'using' kullanarak çok kullanıyorum ve yine burada yine faydalı olduğunu görüyorum! =) – wjl

+0

Daha da iyisi, bu daha fazla anlaşılabilir olan, unique_list_base :: unique_list_base; kullanarak devralınan yapıcı satırını değiştirmeme izin veriyor. – wjl

2

Kolay:

template <typename U, typename thebase=base<U>> 
struct derived : thebase { 
    using thebase::thebase; 
}; 

dezavantajı iki şablon argümanları var şablonun dış arabirim değiştirmesidir. Böyle olduğu çözebilir:

template <typename U, typename thebase=base<U>> 
struct derived_impl : thebase { 
    using thebase::thebase; 
}; 
template<typename U> 
using derived = derived_impl<U>; 
0

Aslında, MSVC, gcc aksine, hatta şablon argümanı tekrar gerektirmediğini görüntülenir: biri sadece "baz :: tabanını kullanarak" yazabiliriz.

İlgili konular