0%

C++的一些踩坑记录

声明和定义

  • 正常情况下,函数的声明和定义可以分开写,如果函数参数有默认参数,写在声明或定义处都没问题,如果函数为模板参数,那么默认参数只能写在声明处

模板函数

模板函数用于将同一个函数对不同类型生效,一般来说,最好不要用 auto 来捕获,写模板函数才是正确的方式。

模板函数的声明和定义一般不能分开。

隐式指定

如果你想偷懒,就是调用的时候不想写 <T1,T2...>,那么你调用的时候必须能让编译器推断出每个模板类型参数是什么,而且同一种类型不能冲突。

这里需要注意字面量的类型问题。

注意,如果你使用了默认参数,那么调用的时候可能就无法让编译器推断出类型从而出现 CE

1
2
3
4
5
6
7
8
template<typename T1,typename T2>
void add(T1 x,T1 y,T2 len=30);
add(1,1);//CE
add(1,1,30);//OK
template<typename T1,typename T2>
void add(T1 x,T2 y,T2 len=30);
add(1,1.5);//OK
add(1,1.5,30);//CE

类型参数捕获比较阴间的例子,可以发现它会先捕获”简单”的,不太想深究这个:

1
2
3
4
template<typename T1,typename T2>
void add(vector<T1> a,T1 b,T2 c);
add({1.5,3},1.5,5);//ok
add({1.5,3.5},1,5);//CE

显式指定

如果显示指定参数,那么会出现类型强制转换,和正常的函数调用完全相同。

例子就不举了,和正常函数没差别。

指针

常量指针

1
2
const int* p = &a; //指向常量的指针
int* const p = &a; //p 指向的位置不可变