In C++, how does one find the type of a variable?
- 5Possible duplicate of stackoverflow.com/questions/81870/print-variable-type-in-ctheharshest– theharshest2012-07-03 12:29:53 +00:00Commented Jul 3, 2012 at 12:29
- 9cout << typeid(variable).name() << endl;SRN– SRN2012-07-03 12:30:19 +00:00Commented Jul 3, 2012 at 12:30
- 3Use the search or google :) stackoverflow.com/questions/81870/print-variable-type-in-c Theharshest is fast :DKariboo– Kariboo2012-07-03 12:32:52 +00:00Commented Jul 3, 2012 at 12:32
- 44@Kariboo, I used Google and it sent me here.Michael Warner– Michael Warner2015-08-27 23:57:22 +00:00Commented Aug 27, 2015 at 23:57
- 1This question is very unclear as it is, and even after seeing the various answers; it is by no means clear that the question is seeking the accepted answer.Antti Haapala– Antti Haapala2016-09-21 07:51:04 +00:00Commented Sep 21, 2016 at 7:51
11 Answers
You can use the typeid operator:
#include <typeinfo> ... cout << typeid(variable).name() << endl; 4 Comments
i means integer on your compiler. The names returned are not specified by the standard.typeid are very abbreviated, compiler-specific, and not intended for human consumption. You can "demangle" them (that's the actual term!), either in code with something like gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html, with command line utilities such as c++filt, or with any of various online demanglers such as demangler.com.For static assertions, C++11 introduced decltype which is quite useful in certain scenarios.
3 Comments
decltype can be used for more than just static assertions. For example, decltype(a) b; declares b as the same type as a.#define ACQUIRE_LOCK(lock) std::unique_lock<decltype(lock)> _unique_lock(lock)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
Comments
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)
5 Comments
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 } 3 Comments
typeid simply cannot be a static, compile-time check - by definition - so this doesn't facilitate any optimisation. For a template function, I need to special case the code based on the template variable Right, so what you really want is static polymorphism via the CRTP idiom. This is exactly what that achieves.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.
3 Comments
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.
Comments
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 } 5 Comments
.name(), so you can disable demangling with #ifdef _MSC_VER.clang-cl also defines __clang__, and while I can't test it right now, I don't think it ships __cxa_demangle and it should return nice names directly from .name(). Testing just __GNUC__ alone should work, since clang but not clang-cl should define it. Testing _MSC_VER should also work, it's defined by MSVC and clang-cl. Also, defined A || B should be defined A || defined B.if defined construct. I checked the example by clang 13.0.0. It works correctly. rextester.com/IXJH71787clang-cl, not on clang.clang-cl right now either. However, for clang, the __GNUC__ macro is sufficient. If anyone can check this example for clang-cl, feel free to edit this code to make it cross-compile.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.
3 Comments
std::cout << "I'm a variable of type " << typeid(n).name(). (reworded to prevent a/an artifacts, but that can be fixed with another check). Even then, if you absolutely want a comparison, it's so much better to do typeid(n) == typeid(int)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 ==).