2014-12-17 4 views
6

В C++ 03, когда вы используете оператор typeid, возвращается объект type_info.Извлечение размера типа данных из std :: type_info

Возможно ли получить размер данного типа, основанный только на этом результате, например, возвращаемом оператором sizeof?

Например:

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

Вопрос заключается в том, что мы используем сторонний мульти-класс массива, который дает обратно type_info, но не размер типа.

+1

Почему бы просто не использовать тип напрямую? Для чего это нужно? – rubenvb

+0

Мы используем сторонний многоаспектный класс, который возвращает тип type_info, но не размер этого типа. – Schiavini

+0

Нет такого объекта, насколько я могу видеть ... – ravi

ответ

1

Лучший способом я могу видеть (я хотел бы быть опровергнут) является заранее зарегистрировать типы, например:

#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 
} 

Возможного выход:

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 

Если вы можете контролировать как вы создаете массивы (например, с помощью фабричного метода), вы можете напрямую зарегистрировать здесь тип.

+1

IIRC, нет гарантии, что все вызовы 'typeid' с одним и тем же типом возвращают один и тот же экземпляр' type_info'. Поэтому 'type_info' не следует сравнивать по его адресу. Для обхода этого 'type_index' был добавлен в C++ 11. Если вы не можете использовать C++ 11, напишите свою собственную оболочку. – magras

Смежные вопросы