2012-03-25 25 views
11

Böyle bir özyinelemeli veri türü var. Bir yerde hata mı yapıyorum? ya da bu standardın bir parçası mı?şablonlu özyinelemeli veri tipleri

Ben de bir şablon parametresi (std::stack ve std::queue benzeri) tarafından belirlenen iç konteyner istiyorum, ama bu zaten tanımlanmış olması sometype gerektirecektir beri bunu yapmak için bir yolunu olamaz.

Eksik örnek:

template<typename T, typename C = std::map<T, SomeType<[???]>>> 
struct SomeType { 
    C mapping; 
}; 

SomeType<int, [???]> foo; 

bu çalışma zamanı dolaylama ile yapılabilir biliyorum, ama bu benim aradığım şey bu değil.

+1

şablonlar tam türleri ile bunları örneğini gerektirir standart kütüphane konteyner; her şey tanımlanmamış davranıştır. Bununla yaşamak zorundasın. Yine de bunun için çalışmak için bir pimpl çözümü kullanabilirsiniz. –

+0

@KerrekSB Öyle mi? Lanet olsun, düzenli olarak n-ary ağaçları yazdım, düğümleri std :: vector çocuklar 'olarak uygulandı. –

+0

@KonradRudolph: Peki, örnekleme zamanında tipin tamamlandığından emin olmalısınız. Bu ince bir sorun olabilir. –

cevap

7

Sınıfınız, tanımının son } tarihinden önce hiçbir yerde eksik. Bu nedenle, mapping üye, türünün şablon argümanlarında eksik SomeType eksik kullanıyor.

The standard does not allow this, and it is pure luck that it works with some STL containers.

Kişisel ikinci soru aynı cevap kapsamına girer - ilk etapta bunu yapmak yasaktır.

+0

Hmm. Maalesef, makalenin eksik türleri ile std :: map 'niçin ilke olarak çalışamadığı hakkındaki argümanını anlamıyorum. Bu, std :: vector > 'gibi çok fazla bir şey değil, * prensipte çalışabilir ('std :: pair ' eksiktir)? Aynı diğer kaplar için de geçerli. –

+0

Bu bir açıklama gerektiriyorsa, bir sohbet odası açmanızı öneririm, bu zor değil, yorum bölümü için uygun değil ... Şimdi, bir sohbet odasını bu konuda açık bir şekilde nasıl açabilirim ... – Irfy

+1

Haydi sohbet edelim: http://chat.stackoverflow.com/rooms/9282/stl-with-incomplete-types – Irfy

4

Belirgin nedenlerle tekrarlı varsayılan parametrelere sahip bir şablon tanımlayamazsınız. Standart kütüphane şablonlarını tamamlanmamış türlerde de başlatamazsınız, çünkü standart böyle söylemektedir (aksi halde tanımlanmamış bir davranışdır). Her zamanki Pimpl deyim olsa yardımcı olabilir: Eğer konteynerler ile eksik türleri kullanmak edemesek

#include <map> 
#include <memory> 
template <typename T> class SomeType 
{ 
    typedef std::map<T, SomeType<T>> map_type; 
    typedef std::unique_ptr<map_type> map_ptr; 
    map_ptr pimpl; 
public: 
    SomeType() : pimpl(new map_type) { } 
}; 
+1

Yükseltme :: kapsayıcı kitaplığı, tamamlanmamış türlerde tekrarlanan kaplara izin veren çoğu STL türü için alternatifler sunar. Şu anda unordered_map – mark

+0

@mark sağlamaz: Teşekkürler, bilmek güzel! –

3

, akıllı işaretçiler ile yapabilirsiniz. Ve tanımsız türleri parametrelerle şablon türlerini oluşturamaz ise, buradan bazı hileler kullanabilirsiniz:

template<typename T, template <typename U, typename V, typename... Args> class Container = std::unordered_map > 
struct SomeType { 
    Container<T, std::unique_ptr<SomeType> > mapping; 
}; 
+0

İlk satırı, kapsayıcının varsayılan değeri std :: vektörü olacak şekilde değiştirmek mümkün müdür? –

+0

@NielsLohmann, teknik olarak 'template class Container = std :: vector>' yazabilir, ancak std :: unordered_map' ile tutarsız olur. Çünkü harita _assosiative_ conrtainer ve vektör sadece bir dizidir. – Lol4t0