前言
我們很常會想要知道一個 C++ 變數的 資料型態 (type),
但 C++ 難道沒有像 python 一樣直接 type() 就能直接看出資料型態 (type) 的 function 嗎?
雖然有點不同,但其實還是有的!!!
我覺得這篇應該會有很多人有跟我一樣的問題!!
使用方法 – 主要使用 typeid 相關的功能
typeid(T).name()
範例程式碼
#include <iostream>
using namespace std;
int main()
{
const char* s = "Hello";
cout << typeid(s).name() << endl;
return 0;
}
編譯與結果
> g++ test.cpp -std=c++11 -o a.out && ./a.out
PKc
「PKc」就是我們得到的結果,但我們看不懂啊!!!似乎我們還要想辦法去翻譯一下?
註:
我們印出來的是 g++ decorated name,也就是說我們需要去解構 (demangle) 他,詳細可參考下方連結。
What you get from g++ is a decorated name, that you can “demangle” using the c++filt command or __cxa_demangle.
參考此文:https://stackoverflow.com/questions/4465872/why-does-typeid-name-return-weird-characters-using-gcc-and-how-to-make-it-prin
整理格式
依照上方連結的作法,我們在編譯時稍微修改一下 flag,
編譯與結果
❯ g++ datatype_test.cpp -std=c++11 -o a.out && ./a.out | c++filt --types;
char const*
「char const*」就是我們得到的結果,我們終於看得懂啦!!!
Playground – 觀察 char array, char*, string, stringstream 之間的關係 (可觀察變化學習),後續會有文章專門討論
範例程式碼
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
int a = 2;
float b = 3.0;
char s0[10] = "Hello";
char s1[] = "Hello";
const char* s2 = "Hello";
string s3 = "Hello";
stringstream s4;
cout << typeid(a).name() << ", " << a << endl;
cout << typeid(b).name() << ", " << b << endl;
cout << " ------ s0 testing ------ " << endl;
cout << typeid(s0).name() << ", " << s0 << endl;
cout << " ------ s1 testing ------ " << endl;
cout << typeid(s1).name() << ", " << s1 << endl;
cout << " ------ s2 testing ------ " << endl;
cout << typeid(s2).name() << ", " << s2 << endl;
cout << " ------ s3 testing ------ " << endl;
cout << typeid(s3).name() << ", " << s3 << endl;
cout << " ------ s4 testing ------ " << endl;
cout << typeid(s4).name() << endl;
s4 << s3;
cout << typeid(s4).name() << endl;
cout << typeid(s4.str()).name() << ", " << s4.str() << endl;
cout << typeid(s4.str().c_str()).name() << ", " << s4.str().c_str() << endl;
return 0;
}
編譯與結果
> g++ datatype_test.cpp -std=c++11 -o a.out && ./a.out | c++filt --types;
int, 2
float, 3
------ s0 testing ------
char [10], Hello
------ s1 testing ------
char [6], Hello
------ s2 testing ------
char const*, Hello
------ s3 testing ------
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Hello
char const*, Hello
------ s4 testing ------
std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >
std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Hello
char const*, Hello
Refernce
https://stackoverflow.com/questions/4465872/why-does-typeid-name-return-weird-characters-using-gcc-and-how-to-make-it-prin
https://docs.microsoft.com/zh-tw/cpp/cpp/typeid-operator?view=msvc-160
https://en.cppreference.com/w/cpp/language/typeid
https://iter01.com/553394.html
https://github.com/willwray/type_name#HH
https://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c