In C++03, when you use the operator typeid, a type_info object is returned.
Is it possible to retrieve the size of the given type based only on this result, such as returned by the sizeof operator?
For example:
std::type_info info = typeid(int);
int intSize = sizeof(int);
int intSize2 = info.getSize(); // doesn't exist!
The issue is that we use a third-party multi array class that gives back a type_info, but not the size of the type.
std::type_info The class type_info holds implementation-specific information about a type, including the name of the type and means to compare two types for equality or collating order.
The typeid operator returns an lvalue of type const std::type_info that represents the type of expression expr. You must include the standard template library header <typeinfo> to use the typeid operator.
The typeid operator allows the type of an object to be determined at run time. The result of typeid is a const type_info& . The value is a reference to a type_info object that represents either the type-id or the type of the expression, depending on which form of typeid is used.
std::type_index The type_index class is a wrapper class around a std::type_info object, that can be used as index in associative and unordered associative containers. The relationship with type_info object is maintained through a pointer, therefore type_index is CopyConstructible and CopyAssignable.
The best way I can see (I would like to be proven wrong) is to register the types beforehand, like this:
#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
}
Possible output:
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
If you can control how you create the arrays (for example, with a factory method) you can directly register the type here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With