Reputation: 96875
In C++, how does one find the type of a variable?
Upvotes: 270
Views: 681302
Reputation: 445
typeid Operator with abi::__cxa_demangle() (GCC / Clang only)
#include <iostream>
#include <typeinfo>
#if defined __GNUC__
#include <cxxabi.h> // GCC / Clang only
#endif
int main() {
long long w;
std::cout << typeid(w).name() << std::endl; // x
#if defined __GNUC__ // GCC / Clang only
char * name = abi::__cxa_demangle(typeid(w).name(), 0, 0, 0);
std::cout << name << std::endl; // long long
free(name);
#endif
}
Upvotes: 2
Reputation: 1547
If you need to make a comparison between a class and a known type, for example:
class Example{};
...
Example eg = Example();
You can use this comparison line:
bool isType = string( typeid(eg).name() ).find("Example") != string::npos;
which checks the typeid
name contains the string type (the typeid name has other mangled data, so its best to do a s1.find(s2)
instead of ==
).
Upvotes: 0
Reputation: 314
You can definitely go for typeid(x).name()
where x is the variable name. It actually returns a const char pointer to the data type. Now, look at the following code.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 36;
char c = 'A';
double d = 1.2;
if(*(typeid(n).name()) == 'i'){
cout << "I am an Integer variable" << endl;
}
if(*((char *) typeid(d).name()) == 'd'){
cout << "I am a Double variable" << endl;
}
if(*((char *) typeid(c).name()) == 'c'){
cout << "I am a Char variable" << endl;
}
return 0;
}
Notice how first and second both if works.
Upvotes: 1
Reputation:
For static assertions, C++11 introduced decltype
which is quite useful in certain scenarios.
Upvotes: 69
Reputation: 41767
You can use the typeid operator:
#include <typeinfo>
...
cout << typeid(variable).name() << endl;
Upvotes: 282
Reputation: 126
I'm not sure if my answer would help.
The short answer is, you don't really need/want to know the type of a variable to use it.
If you need to give a type to a static variable, then you may simply use auto.
In more sophisticated case where you want to use "auto" in a class or struct, I would suggest use template with decltype.
For example, say you are using someone else's library and it has a variable called "unknown_var" and you would want to put it in a vector or struct, you can totally do this:
template <typename T>
struct my_struct {
int some_field;
T my_data;
};
vector<decltype(unknown_var)> complex_vector;
vector<my_struct<decltype(unknown_var)> > simple_vector
Hope this helps.
EDIT: For good measure, here is the most complex case that I can think of: having a global variable of unknown type. In this case you would need c++14 and template variable.
Something like this:
template<typename T> vector<T> global_var;
void random_func (auto unknown_var) {
global_var<decltype(unknown_var)>.push_back(unknown_var);
}
It's still a bit tedious but it's as close as you can get to typeless languages. Just make sure whenever you reference template variable, always put the template specification there.
Upvotes: 4
Reputation: 13394
If you have a variable
int k;
You can get its type using
cout << typeid(k).name() << endl;
See the following thread on SO: Similar question
Upvotes: 24
Reputation: 129
I believe I have a valid use case for using typeid(), the same way it is valid to use sizeof(). For a template function, I need to special case the code based on the template variable, so that I offer maximum functionality and flexibility.
It is much more compact and maintainable than using polymorphism, to create one instance of the function for each type supported. Even in that case I might use this trick to write the body of the function only once:
Note that because the code uses templates, the switch statement below should resolve statically into only one code block, optimizing away all the false cases, AFAIK.
Consider this example, where we may need to handle a conversion if T is one type vs another. I use it for class specialization to access hardware where the hardware will use either myClassA or myClassB type. On a mismatch, I need to spend time converting the data.
switch ((typeid(T)) {
case typeid(myClassA):
// handle that case
break;
case typeid(myClassB):
// handle that case
break;
case typeid(uint32_t):
// handle that case
break;
default:
// handle that case
}
Upvotes: 12
Reputation: 20769
The main difference between C++ and Javascript is that C++ is a static-typed language, wile javascript is dynamic.
In dynamic typed languages a variable can contain whatever thing, and its type is given by the value it holds, moment by moment. In static typed languages the type of a variable is declared, and cannot change.
There can be dynamic dispatch and object composition and subtyping (inheritance and virtual functions) as well as static-dispatch and supertyping (via template CRTP), but in any case the type of the variable must be known to the compiler.
If you are in the position to don't know what it is or could be, it is because you designed something as the language has a dynamic type-system.
If that's the case you had better to re-think your design, since it is going into a land not natural for the language you are using (most like going in a motorway with a caterpillar, or in the water with a car)
Upvotes: 16
Reputation: 17278
Usually, wanting to find the type of a variable in C++ is the wrong question. It tends to be something you carry along from procedural languages like for instance C or Pascal.
If you want to code different behaviours depending on type, try to learn about e.g. function overloading and object inheritance. This won't make immediate sense on your first day of C++, but keep at it.
Upvotes: 8