类型推导
auto自动推导
概念
拥有自动推导数据类型的功能
语法:auto 变量名 = 表达式;
举例:
原来:C++定义变量的方式int num = 10;
现在:可以对数据类型推导auto num = 10;
使用方法:
- 修饰变量时,和
const
类似,在定义时就必须初始化 - 可以作为函数的返回类型,则会自动推导
用途:
对于繁琐的数据类型可以使用auto,以此缩减代码量,比如
for(vector<int>::iterator it = v.begin(); it != v.end(); it++){}
可以转换成
for(auto it = v.begin(); it != v.end(); it++){}
注意事项
- 定义的时候就需要被初始化
//auto a; //常见错误1,定义时没有初始化
auto a = 10;
- auto不是数据类型,不能用
sizeof(auto)
和typeid(auto).name()
std::cout << sizeof(auto) << std::endl; //报错
std::cout << typeid(auto).name() << std::endl; //报错
- auto不能作为自定义数据类型数据的成员变量
class MyClass{
// auto i; //报错
int ID;
};
- auto作为参数的问题,在有的编译器中不行比如vs,但是部分部分编译器上这是不报错了比如qt的纯C++项目。
void func(auto val){
val+=1;
}
- auto推导的序列类型必须一致
auto a = 10, b = 11, c = 12;
//auto a1 = 10, b = "11", c = 3.14; //报错
- auto、 const auto& 、auto &、auto &&的区别
效率上auto & = auto && >const auto&>auto
写法 | 说明、用途 |
---|---|
auto | 涉及到拷贝构造。 相当于拷贝出一份新的数据,修改新数据不影响旧数据 |
auto & | 不涉及拷贝构造 相当于引用旧数据,修改后会影响旧数据 |
auto && | 不涉及拷贝构造 相当于右值引用旧数据,修改后会影响旧数据 |
const auto& | 应用于只读模式,不涉及拷贝构造 不可修改数据 |
class StudentVect {
public:
StudentVect() {
for (int i = 0; i < 5; i++)
{
this->IDVect.push_back(i);
}
}
//拷贝构造重写
StudentVect(const StudentVect & Obj) {
cout << "涉及到拷贝构造" << endl;
for (auto i : Obj.IDVect) {
IDVect.push_back(i);
}
}
void showSourceData() {
for (auto it = IDVect.begin(); it != IDVect.end(); it++) {
cout << *it<<" ";
}
cout << endl;
}
//使用const_iterator来读取容器,并且切设置为常函数
void constShowData() const {
for (vector<int>::const_iterator it = IDVect.begin(); it != IDVect.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void changeData() {
for (auto it = IDVect.begin(); it != IDVect.end(); it++) {
*it = *it + 1;
}
}
vector<int> IDVect;
};
void func1() {
StudentVect vct;
vct.showSourceData();
cout << "----auto----" << endl;
auto vct2 = vct;
vct2.changeData();
vct2.showSourceData();
vct.showSourceData();
cout << "----auto &----" << endl;
auto &vct3 = vct;
vct3.changeData();
vct3.showSourceData();
vct.showSourceData();
cout << "----auto &&----" << endl;
auto &&vct4 = vct;
vct4.changeData();
vct4.showSourceData();
vct.showSourceData();
cout << "----const auto &----" << endl;
const auto &vct5 = vct;
//vct5.changeData(); //不能修改,vct5为const类型
//vct5.showSourceData(); //vct5有const修饰,普通迭代器(iterator)已不能使用,需要使用const_iterator
vct5.constShowData(); //常对象只能调用到常函数
vct.showSourceData();
}
运行速率参考 http://t.csdn.cn/jjgnO
decltype自动推导
概念
和auto类似现实自动推导,可传入变量、表达式、函数名来推导出类型。
decltype(变量名)
即使这个变量是const又或者是引用,decltype都能推导出来。
void func2() {
//内置数据类型
int a = 10;
decltype(a) b = 11;
cout << "b的值为 " << b << endl;
//const类型
const int cst_int = 100;
decltype(cst_int) cst_int_test = 11;
cout << "cst_int_test的值为 " << cst_int_test << endl;
// cst_int_test = 100; //这句直接报错
//自定义数据类型
struct MyStruct
{
int ID = 10;
}Obj1, *Obj2; //创建一个普通变量,和指针变量
decltype(Obj1) c;
c.ID = 20;
cout << "c的ID值为 " << c.ID << endl;
decltype(Obj2) d = new MyStruct; //自动识别为自定义类型的指针类型
d->ID = 30;
cout << "d的ID值为 " << d->ID << endl;
delete d;
}
decltype(函数名)
int m_add(int a, int b) {
return a + b;
}
int m_sub(int a, int b) {
return a - b;
}
void func4(int(*p)(int, int), int a, int b) {
cout << p(a, b) << endl;
}
//例子1
void func3() {
decltype(m_add)* a = m_sub; //因为m_add的函数类型和m_sub的函数类型一致,所以用m_add推导m_sub是没问题的
cout << a(5, 6) << endl; //输出-1
}
//例子2
void func5() {
decltype(m_add)* a = m_sub;
func4(a, 20, 10); // 输出10
}
decltype(表达式)
程序并不会真正的去运行这个表达式,但是他会推导出这个表达式的返回类型。
//自定义数据类型
struct MyStruct
{
MyStruct(int count):ID(count){}
int ID;
MyStruct& operator+(MyStruct &obj) {
ID = obj.ID + ID;
return *this;
}
};
void func6() {
//内置数据类型
string a = "12", b = "34";
decltype(a + b) c = "56";
cout << a + b + c << endl;
//自定义数据类型
MyStruct m_a(5), m_b(6);
MyStruct m_c(10);
decltype(m_a + m_b) m_d = m_c;
cout << m_d.ID << endl;
}
追踪返回类型
该方法和python的追踪返回类型一样,都是在函数参数列表后面加上->
来指定函数返回的类型
语法
函数返回类型 函数名() ->指定要返回的类型
{
函数体
}
比如
auto func(int a, long long b)->decltype(a+b)
{
return a+b;
}
用途
结合auto
和decltype
来确定函数的返回类型。常用于模板