Reputation: 41
I am trying to create and store a type_info object:
#include <typeinfo>
int i;
type_info x = typeid(i);
And an error message is generated. Is there any way to store a type_info object?
The history behind this is that I am trying to generate test cases for various C++ integer types; doing arithmetic on them and determining whether intermediate results are promoted to the next largest integer type or truncated. That is:
unsigned char x = 257;
unsigned char y = 257;
// is (x + y) == 514 or 256?
And decided to do a type check against a static data structure, for example:
int x = <value>;
int y = <value>;
static type_info def = { typeid(bool)
, typeid(char), typeid(unsigned char)
, typeid(short), typeid(unsigned short)
, typeid(long), typeid(unsigned long)
};
type_info obj = typeid(x + y);
for(int i = 0; i < sizeof(def)/sizeof(def[0]); i++) if (obj == def[i]); break;
Anyhow, it can't be done without being able to store the type_info structure and I would still like to find out about integer promotions.
Can you create a type_info object? The gcc 4.5.3 implementation has assignment as private.
Is there a resource telling when integer promotions are performed?
thanks
Upvotes: 4
Views: 6059
Reputation: 19120
type_info
is not copy-constructible, but there's a wrapper for it, called type_index
, which is. And it also provides name()
and hash_code()
methods as well as comparison operators, so for most purposes it's just as good as a copy of type_info
— or even better, since it's ordered, unlike type_info
.
Upvotes: 0
Reputation: 93720
typeid()
returns a const type_info &
and type_info
has a private copy constructor, so you can't build the array you describe. I can't find anything to say whether they are persistent, but you could try type_info *a[] = { &typeid(int), ... }
Upvotes: 5
Reputation: 275385
In C++11, (gcc 4.5.1 works) this kind of thing may work:
#include <type_traits>
template<typename... Types>
struct Seq {};
template<typename T, typename Seq, typename=void>
struct IndexOf;
template<typename T, typename First, typename... Types>
struct IndexOf<T, Seq<First, Types...>, typename std::enable_if< std::is_same<T, First>::value >::type > {
enum { value = 0 };
};
template<typename T, typename First, typename... Types>
struct IndexOf<T, Seq<First, Types...>, typename std::enable_if< !std::is_same<T, First>::value >::type > {
enum { value = 1+IndexOf<T,Seq<Types...>>::value };
};
typedef Seq< bool, char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long > IntegerTypes;
#include <iostream>
int main() {
int x = 7;
int y = 10;
std::cout << IndexOf< decltype(x+y), IntegerTypes >::value << "\n";
// this next line will not compile, because void is not in the IntegerTypes sequence:
// std::cout << IndexOf< void, IntegerTypes >::value << "\n";
}
but you'll note it doesn't depend on the values of x or y, just their types.
Note that all of the logic is done at compile time, not at run time. And if you pass a type that isn't in the list, you get a spew of error messages (whose proper interpretation is "not found"). I could have made the error messages shorter, but I'm lazy. :)
Upvotes: 0