下面是用來輸出變數信
息的宏:
#define typeof(typevar) /<br /> do { /<br /> string tmp; /<br /> cerr << "type of "#typevar" :"; /<br /> tmp = "c++filt -t "; /<br /> system((tmp + typeid(typevar).name()).c_str()); /<br /> } while(0);<br />
在這個宏定義裡面,
do
{} while(0);結
構是為了讓
tmp這個變數不會和別的變數產生命名衝突。用
cerr
<< “type of “#typevar”
:”而
不用
cout,是為了關閉輸出緩衝,一般情況下
cout會緩衝,而
cerr是不會緩衝的。
c++filt是
binutils工具包中的一個實用程
序,用來反向解析
c++的名字修飾,它也可以用來反向解析
java中的變數名修飾。使用
這個工具的原因是
typeinfo的輸出沒有標準,不同的編譯器輸出不一樣,在
g++中,比如對於
int
a[4],
輸出的是
A4i,不方便閱讀,如果使用的
cl編譯器,就可能不需要
這個工具。
下面是測試代碼:
#include <iostream>#include <string>#include <typeinfo>using namespace std;#define typeof(typevar) / do { / string tmp; / cerr << "type of "#typevar" :"; / tmp = "c++filt -t "; / system((tmp + typeid(typevar).name()).c_str()); / } while(0);int main() { int a[3][4]; cout << "prototype of a: int a[3][4]:/n"; typeof(a); typeof(*a); typeof(&a); typeof(a+1); typeof(*(a+1)); typeof(*(a+1)+1); typeof(a[1]); typeof(1[a]); typeof(a[1] + 1); int b[4]; cout << "/n/n"; typeof(b); typeof(&b); //typeof(&(&b)); // error, &b is lvalue typeof(*(&b)); typeof(b+1); typeof(*(b+1)); typeof(&b + 1); //typeof(&(b+1)); // error, invalid lvalue typeof(*b); int c[3][4][5]; cout << "/n/n"; typeof(c); typeof(*c); typeof(&c); typeof(c+1); typeof(*(c+1)); //typeof(&(c+1)); // error, invalid lvalue int d[1][4]; cout << "/n/n"; typeof(d); typeof(*d); typeof(&d); typeof(d+1); typeof(*(d+1)); return 0;}
輸出結果:
prototype
of a:
int a[3][4]:
type
of a :int
[3][4]
type
of *a :int
[4]
type
of &a
:int (*) [3][4]
type
of a+1 :int
(*) [4]
type
of *(a+1)
:int [4]
type
of *(a+1)+1
:int*
type
of a[1] :int
[4]
type
of 1[a] :int
[4]
type
of a[1] + 1
:int*
type
of b :int
[4]
type
of &b
:int (*) [4]
type
of *(&b)
:int [4]
type
of b+1 :int*
type
of *(b+1)
:int
type
of &b + 1
:int (*) [4]
type
of *b :int
type
of c :int
[3][4][5]
type
of *c :int
[4][5]
type
of &c
:int (*) [3][4][5]
type
of c+1 :int
(*) [4][5]
type
of *(c+1)
:int [4][5]