2014-12-17 17 views
6

C++ 03'te, kullanıcı typeid kullanıldığında, type_info nesnesi döndürülür.Veri türü boyutunu std :: type_info sayfasından alma

Belirtilen türün boyutunu yalnızca sizeof işleci tarafından döndürülen gibi bu sonuca göre almak mümkün mü? Örneğin

:

std::type_info info = typeid(int); 
int intSize = sizeof(int); 
int intSize2 = info.getSize(); // doesn't exist! 

sorunu biz bir üçüncü taraf çoklu dizi bir type_info geri verir sınıfını değil, harflerin büyüklüğü kullanmasıdır. Ben (Ben yanlış kanıtlanmış istiyorum) görebilirsiniz

+1

Neden sadece türü doğrudan kullanmıyorsunuz? Bunu gerektiren şeyi yapmaya ne çalışıyorsunuz? – rubenvb

+0

Tip_info'yu geri veren, ancak türünün boyutunu belirten bir üçüncü parti çoklu dizi sınıfı kullanıyoruz. – Schiavini

+0

Görebildiğim kadarıyla böyle bir tesis yok ... – ravi

cevap

1

iyi yolu bu gibi önceden türlerini kayıt şudur:

#include <typeinfo> 
#include <iostream> 
#include <stdexcept> 
#include <map> 
#include <vector> 

typedef std::map<const std::type_info*, std::size_t> sizes_container; // we cannot use std::type_index, but that's ok - typeid returns const std::type_info&, which refers to an object which lives during the entire lifetime of the program 

sizes_container& sizes() // wrapped in a function to avoid static initialization order fiasco 
{ 
    static sizes_container s; 
    return s; 
} 

template<typename T> 
void register_size() // Register the type. Can be called multiple times for the same type. 
{ 
    sizes().insert(sizes_container::value_type(&typeid(T), sizeof(T))); 
} 

class no_such_type : public std::domain_error 
{ 
public: 
    no_such_type(const std::string& str) : 
     std::domain_error(str) 
    { 

    } 
}; 

std::size_t get_size(const std::type_info& typeinfo) 
{ 
    sizes_container::iterator it = sizes().find(&typeinfo); 
    if(it != sizes().end()) 
    { 
     return it->second; 
    } 
    else 
    { 
     throw no_such_type(std::string("No type ") + typeinfo.name() + " registered"); 
    } 
} 

int main() 
{ 
    register_size<int>(); 
    register_size<std::vector<int> >(); 

    std::cout << get_size(typeid(int)) << "\n" // get the size from std::type_info, possibly at runtime 
       << get_size(typeid(std::vector<int>)) << "\n" << std::flush; 
    std::cout << get_size(typeid(long)); // if the type isn't registered, the exception no_such_type is thrown 
} 

Olası çıkışı:

4 
24 

This application has requested the Runtime to terminate it in an unusual way. 
Please contact the application's support team for more information. 
terminate called after throwing an instance of 'no_such_type' 
    what(): No type l registered 

kontrol edebilirsiniz varsa dizileri nasıl oluşturursunuz (örneğin, bir fabrika yöntemiyle), buraya doğrudan yazabilirsiniz.

+1

IIRC, "typeid" ile aynı türdeki tüm çağrıların, aynı tür "type_info" döndürdüğüne dair bir garanti yoktur. Yani 'type_info' adresi ile karşılaştırılmamalıdır. Geçici çözüm için bu 'type_index' C++ 11'e eklendi. C++ 11'i kullanamıyorsanız kendi ambalajınızı yazın. – magras