如何查看类型推断结果

这里需要用到boost库,需要https://www.boost.org/下载其库,并在vs项目属性中VC++目录的包含目录中添加boost的地址

理解函数模板类型推断,查看类型推断,auto类型推断

如何查看类型推断结果

当前要解决的问题:如何查看类型推断结果–指编译器给我们进行类型推断的结果
目的:希望通过”查看编译器类型推断结果”的手段来学习并掌握c++类型推断的规则

如何查看编译器帮助我们进行类型推断的结果

  • 依赖Boost库–如何利用库把编译器推断出来的类型打印出来
1
2
3
4
5
6
7
8
9
10
11
12
template<typename T>
void myfunc(const T& tmprv)
{
cout << "------------------------begin--------------------" << endl;
using boost::typeindex::type_id_with_cvr;
cout << "T =" << type_id_with_cvr<T>().pretty_name() << endl;//显示T的类型
cout << "tmprv =" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;
cout << "-------------------------end----------------------" << endl;
}

myfunc(100); //T = int& tmprv = int &
//myfyncT的类型不仅仅取决于实参100,还取决于tmprv的类型(const T&)有关

引用或指针类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<typename T>
void myfunc2( T& tmprv)
{
cout << "------------------------begin--------------------" << endl;
using boost::typeindex::type_id_with_cvr;
cout << "T =" << type_id_with_cvr<T>().pretty_name() << endl;//显示T的类型
cout << "tmprv =" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;
cout << "-------------------------end----------------------" << endl;
}

int i = 18;
const int j = i;
const int& k = i;
myfunc2(i);//猜测下:T=int tmprv=int&
myfunc2(j);//猜测:,有个const,猜不出来,实际:T=int const tmprv=int const&
myfunc2(k);;//也猜不出来 实际:T=int const tmprv=int const&

继续看示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void mf(int& tmprv) {
tmprv = 12;
}

template<typename T>
void mf2(T& tmprv) {
tmprv = 12;
}

template<typename T>
void mf3(T tmprv) {
tmprv = 12;
}

int ii = 1;
int& jj = ii;
mf(jj);
cout << ii <<endl; //12
ii = 1;
mf2(jj);
cout << ii <<endl; //12
ii = 1;
mf3(jj);
cout << ii << endl; //1

函数行参带const区别


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
template<typename T>
void myfunc(const T& tmprv)
{
cout << "------------------------begin--------------------" << endl;
using boost::typeindex::type_id_with_cvr;
cout << "T =" << type_id_with_cvr<T>().pretty_name() << endl;//显示T的类型
cout << "tmprv =" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;
cout << "-------------------------end----------------------" << endl;
}

template<typename T>
void myfunc2( T& tmprv)
{
cout << "------------------------begin--------------------" << endl;
using boost::typeindex::type_id_with_cvr;
cout << "T =" << type_id_with_cvr<T>().pretty_name() << endl;//显示T的类型
cout << "tmprv =" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;
cout << "-------------------------end----------------------" << endl;
}

int iii = 18;
const int jjj = iii;
const int& kk = iii;
myfunc(iii); // T = int tmprv = int&
myfunc(jjj); //T = int tmprv = int const&
myfunc(kk); //T = int tmprv =int const&
myfunc2(iii); // T = int tmprv = int&
myfunc2(jjj); //T = int const tmprv = int const&
myfunc2(kk); //T = int const tmprv =int const&

根据结果:

  1. 如果实参是引用类型,那么引用部分会被忽略,T不会被推导为引用类型

  2. 当向引用类型的形参tmprv传入const 类型实参时,形参就会变成const&

    • 实参的const属性会成为类型模板参数T类型推导的组成部分,所以不用担心在myfunc会修改原来const属性的实参

    • 如果实参是引用类型,那么引用部分会被忽略,T不会被推导为引用类型

    • T中的const没有了,因为函数模板出现const修饰符,当不管怎么说,只要实参带const,形参tmprv中终究会带着const


形参中引用有两个作用:

  1. 可以修改外面实参的值

  2. 是传递引用比传值效率高

一般来说,函数模板的形参建议优先考虑T& 的形态
这样的形态,不怕实参的引用被忽略掉而导致开发者想通过对形参的修改达到修改实参的本意无法达成
如何即想享受形参为引用带来效率上的提高,又不希望通过形参来修改实参,则函数模板中的形参考虑const T&


如果tmprv是个指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<typename T>
void func3(T* tmprv) {
cout << "------------------------begin--------------------" << endl;
using boost::typeindex::type_id_with_cvr;
cout << "T =" << type_id_with_cvr<T>().pretty_name() << endl;//显示T的类型
cout << "tmprv =" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;
cout << "-------------------------end----------------------" << endl;
}

int i = 12;
int n = 18;
int* point = &n;
const int* point2 = &n;

func3(&i); //T =int tmprv =int *
func3(point); //T =int tmprv =int *
func3(point2); //T = int const tmprv =int const *

const版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void func3(const T* tmprv) {
cout << "------------------------begin--------------------" << endl;
using boost::typeindex::type_id_with_cvr;
cout << "T =" << type_id_with_cvr<T>().pretty_name() << endl;//显示T的类型
cout << "tmprv =" << type_id_with_cvr<decltype(tmprv)>().pretty_name() << endl;
cout << "-------------------------end----------------------" << endl;
}


int i = 12;
int n = 18;
int* point = &n;
const int* point2 = &n;

func3(&i); //T =int tmprv =int const *
func3(point); //T =int tmprv =int const*
func3(point2); //T = int tmprv =int const *

结论:

  1. tmprv中没const,则实参中的const会被带到类型T中,如果tmprv中有const,则T类型中不会带const

  2. 与引用类似