规则:
- 顶层const被忽略
- 如果表达式是引用,则返回它所引用的对象的类型
- 当将其作用于函数或数组,不会发生退化(函数退化成函数指针,数组退化成指向数组成员类型的指针)
1 #include <iostream>
2 int add(int a, int b){ return a + b;}
3 int main() {
4 int x;
5 int& rx = x;
6 int* px = &x;
7 const int* cpx = &x;
8 const int* const cpcx = &x;
9 const int y{3};
10 const int& ry = y;
11 const int* cpy = &y;
12 const int* const cpcy = &y;
13 int int_a[] = {1, 2, 3, 4};
14 char char_a[] = "typeid";
15 typedef int(*sub)(int, int);
16
17 std::cout << typeid(x).name() << '\n';
18 std::cout << typeid(rx).name() << '\n';
19 std::cout << typeid(px).name() << '\n';
20 std::cout << typeid(cpx).name() << '\n';
21 std::cout << typeid(cpcx).name() << '\n';
22 std::cout << typeid(y).name() << '\n';
23 std::cout << typeid(ry).name() << '\n';
24 std::cout << typeid(cpy).name() << '\n';
25 std::cout << typeid(cpcy).name() << '\n';
26 std::cout << typeid(int_a).name() << '\n';
27 std::cout << typeid(char_a).name() << '\n';
28 std::cout << typeid(add).name() << '\n';
29 std::cout << typeid(sub).name() << '\n';
30 }
输出
i
i
Pi
PKi
PKi
i
i
PKi
PKi
A4_i
A7_c
FiiiE
PFiiiE
为了方便理解,这里将返回的类型名称进行还原
[-bash-4.2 $]c++filt -t "PFiiiE"
int (*)(int, int)
[-bash-4.2 $]c++filt -t "FiiiE"
int (int, int)
[-bash-4.2 $]c++filt -t "A4_i"
int [4]
[-bash-4.2 $]c++filt -t "A7_c"
char [7]
[-bash-4.2 $]c++filt -t "PKi"
int const*
[-bash-4.2 $]c++filt -t "Pi"
int*
[-bash-4.2 $]
17-18 : int 和 int& 都输出i,即引用类型返回该引用所引用的对象的类型
20-21,24-25: 顶层const被忽略
对比17和22可以看到,顶层const被忽略
26-27:可以说明数据未发生退化
28:是函数的类型名称,与29函数指针的名称不相同,即函数也没有退化为函数指针
此外,当涉及继承时还有一些细节需要考虑,未来会在另一篇文章中讨论。