2016-04-12 26 views
0

C++ uygulamasında, bir dizeyi rasgele bir türle ilişkilendirmeme olanak tanıyan bir istatistik sistemi oluşturmaya çalışıyorum. Şu anda, bu tür bir enum ile çalışan ve bu nesneyi işaret eden bir void * çalışıyorum var, ancak bu desteklemek istediğim tüm türleri için bireysel if ifadeleri yapmak gerekir. Bir çeşit şablon kullanarak herhangi bir keyfi türü destekleyebilmem için sahip olmak isterim. Ben bazı test kodu işlerin bu tür oluşturduk fakat sorunlar vardır:Nesne, türü ile ilişkilendirme

Bugüne kadar işler var, ama bir yıkıcı uygulamak mümkün olacağını düşünüyorum veya kopyalama yok ne
class Test { 
    std::type_index type; 
    void *value; 

public: 
    template <typename T> 
    Test(T val) : type(typeid(val)) { 
     T *val_p = new T; 
     *val_p = val; 
     value = (void *)val; 
    } 

    Test() : type(typeid(void)) { 
     value = nullptr; 
    } 

    ~Test() { 
     //no idea how I could make this work 
    } 

    template <typename T> 
    T get() { 
     if (std::type_index(typeid(T)) == type) { 
      T *val_p = (T *)value; 
      return *val_p; 
     } else { 
      throw std::bad_typeid(); 
     } 
    } 
}; 

/hamle kurucular . Bütün bir nokta, hepsini tek bir std::unordered_map içinde saklamak istiyorum, bu yüzden (AFAIK) bir şablon sınıfı yapıp oradan gidemem. Yani, yapmaya çalıştığım şeyi yapmak mümkün mü ve eğer öyleyse, nasıl yaparım?

+0

saklar. – CodeMouse92

+0

Takviye ihtiyacınız var gibi görünüyor: variant. –

+1

"Boost :: any" aradığınız görünüyor. Genellikle gerçekten bir varyantı istiyorsun ('boost :: variant'). – GManNickG

cevap

0

GManNickG önerisine dayanarak, aradığım şeylere çok benzediğinden boost::any ile gidiyorum.

Henüz koduna uygulanmadı var, ancak temel yapı çizgisinde bir şey olacaktır

: Ben yıkıcılar veya kopyala/hareket ile uğraşmak gerekmez Bununla

#include <typeinfo> 
#include <boost/any.hpp> 

class Statistic { 
    boost::any value; 

public: 
    template <typename T> 
    Statistic(T val) : value(val) {} 

    Statistic() : value() {} 

    template <typename T> 
    bool checkType() { 
     return typeid(T) == value.type(); 
    } 

    //Will cause an exception if the type doesn't match 
    //Caller should check type if unsure 
    template <typename T> 
    T get() { 
     if (checkType<T>()) { 
      return boost::any_cast<T>(value); 
     } else { 
      //throw some exception 
      throw bad_any_cast(); 
     } 
    } 
} 

örtük olanlar, destek kitaplığı tarafından zaten uygulanan kodu çağıracağından, işlevler.

DÜZENLEME: Bir `Sendikası`nın sizin için yararlı olabilir, bu keyfi türlerini daraltmak Eğer boost::any işaret için milleniumbug için sayesinde zaten std::type_info

+0

Bu cevabı, bu sorunun cevabını gelecekte aynı sorunlara sahip insanlara yardımcı olabilecek bir şeye dönüştürmek için nihai çözümünüzle biraz doldurun. Şu anda bu cevap temel olarak yem düşürmekten ibarettir. – user4581301

+2

'Boost :: any' zaten sizin için' std :: type_info' öğesini kaydettiğine dikkat edin (bkz. '.type()') – milleniumbug

+0

Ah teşekkürler. Daha az ihtiyaç duyulan istisnaları yapmak için bunu yapıyordum, ama bu daha kolay –

İlgili konular