C++ 印出變數類型

本篇 ShengYu 介紹 C++ 印出變數類型,使用 typeid 可以取得該變數類型的資訊,

要使用 typeid 的話,需要引入的標頭檔<typeinfo>

C++ 印出變數類型

使用 typeid(變數名稱).name() 可以回傳該變數的變數類型。

cpp-typeid.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// g++ cpp-typeid.cpp -o a.out -std=c++11
#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
using namespace std;

int main() {
char c;
cout << "char:" << typeid(c).name() << "\n";
unsigned char uc;
cout << "char:" << typeid(uc).name() << "\n";

short s;
cout << "short:" << typeid(s).name() << "\n";
unsigned short us;
cout << "unsigned short:" <<typeid(us).name() << "\n";

int i;
cout << "int:" << typeid(i).name() << "\n";
unsigned int ui;
cout << "unsigned int:" << typeid(ui).name() << "\n";

long l;
cout << "long:" << typeid(l).name() << "\n";
unsigned long ul;
cout << "unsigned long:" << typeid(ul).name() << "\n";

float f;
cout << "float:" << typeid(f).name() << "\n";
double d;
cout << "double:" << typeid(d).name() << "\n";

char ac[10];
cout << "char:" << typeid(ac).name() << "\n";
string str;
cout << "string:" << typeid(str).name() << "\n";
int ai[20];
cout << "array int:" << typeid(ai).name() << "\n";
vector<int> v;
cout << "vector<int>:" << typeid(v).name() << "\n";

return 0;
}

輸出結果如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
char:c
char:h
short:s
unsigned short:t
int:i
unsigned int:j
long:l
unsigned long:m
float:f
double:d
char:A10_c
string:NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
array int:A20_i
vector<int>:St6vectorIiSaIiEE

可以看到這些印出來的型態都不是我們所熟悉的,這時候請使用一個神秘的工具指令叫做 c++filt 就可以印出這些資訊的對應型態了,讓我來示範一下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ c++filt -t c
char
$ c++filt -t h
unsigned char
$ c++filt -t s
short
$ c++filt -t t
unsigned short
$ c++filt -t j
unsigned int
$ c++filt -t m
unsigned long
$ c++filt -t f
float
$ c++filt -t d
double
$ c++filt -t A10_c
char [10]
$ c++filt -t NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
$ c++filt -t A20_i
int [20]
$ c++filt -t St6vectorIiSaIiEE
std::vector<int, std::allocator<int> >

以上的示範是不是超級清楚!可是我想要直接就印出變數類型不想這樣還要透過指令轉一手怎麼辦?

typeid 印出真正的變數類型

如果要將 typeid().name() 的結果印出真正的變數類型的話,可以參考下列方式使用 abi::__cxa_demangle 這個函式,使用前需要引入標頭檔 <cxxabi.h>

cpp-typeid2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// g++ cpp-typeid2.cpp -o a.out -std=c++11
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;

int main() {
int i;
int status;
char *realname = abi::__cxa_demangle(typeid(i).name(), 0, 0, &status);
cout << realname << "\n";
free(realname);

return 0;
}

印出 auto 的變數型態

這邊舉個例子,有時候 STL 回傳的變數類型用 auto 接很方便,但有時候會想要明確知道這個變數類型是什麼,下面以 vector::size() 為例,vector::size() 會回傳 size_type,那 size_type 實際上是被定義成什麼基本變數型態呢?就可以用剛剛學到的技巧來試試,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// g++ cpp-typeid3.cpp -o a.out -std=c++11
#include <iostream>
#include <vector>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;

int main() {
vector<int> v;
auto size = v.size();

int status;
char *realname = abi::__cxa_demangle(typeid(size).name(), 0, 0, &status);
cout << realname << "\n";
free(realname);

return 0;
}

以我的 Ubuntu 64bit 作業系統下輸出結果如下,

1
unsigned long

其它參考
c++ - typeid() returns extra characters in g++ - Stack Overflow
https://stackoverflow.com/questions/789402/typeid-returns-extra-characters-in-g
https://charlottehong.blogspot.com/2017/04/c-typeid.html

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
std::vector 用法與範例
std::deque 介紹與用法
std::queue 用法與範例
std::map 用法與範例
std::unordered_map 用法與範例
std::set 用法與範例
std::thread 用法與範例
std::mutex 用法與範例
std::find 用法與範例
std::sort 用法與範例
std::random_shuffle 產生不重複的隨機亂數
std::shared_ptr 用法與範例
std::async 用法與範例