David G
David G

Reputation: 96875

How do I get the type of a variable?

In C++, how does one find the type of a variable?

Upvotes: 270

Views: 681302

Answers (11)

Kuznetsov-M
Kuznetsov-M

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
}

clang online

Upvotes: 2

jackw11111
jackw11111

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

Pikachu
Pikachu

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

user2074102
user2074102

Reputation:

For static assertions, C++11 introduced decltype which is quite useful in certain scenarios.

Upvotes: 69

Rich O&#39;Kelly
Rich O&#39;Kelly

Reputation: 41767

You can use the typeid operator:

#include <typeinfo>
...
cout << typeid(variable).name() << endl;

Upvotes: 282

gohongyi
gohongyi

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

Amit
Amit

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

Dan Truong
Dan Truong

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

Emilio Garavaglia
Emilio Garavaglia

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

Pontus Gagge
Pontus Gagge

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

rad
rad

Reputation: 1136

#include <typeinfo>

...
string s = typeid(YourClass).name()

Upvotes: 4

Related Questions