auto b; // 错误,需要初始化 int temp = 110; auto *a = &temp; // a 为 int* auto ---> int auto b = &temp; // b 为 int* auto ---> int* auto &c = temp; // c 为 int auto ---> int auto d = temp; // d 为 int auto ---> int
// 使用 auto template <classT> voidfunc(){ auto val = T::get(); cout << "val: " << val << endl; }
intmain(){ func<T1>(); func<T2>(); return0; }
decltype
基础
编译时推导 根据表达式推导类型,但表达式不需要计算,只做类型推导
1 2 3 4 5
// 对于类型推导不确定的,检测 decltype(1.0) x = 1; if (is_same<decltype(x), double>::value) { cout << "x is double" << endl; // 输出这句话 }
表达式为普通变量或者普通表达式或者类表达式
1 2 3 4 5 6 7 8
int x = 99; constint &y = x; decltype(x) a = x; // int decltype(y) b = x; // const int & decltype(2) c = x; // 2 为 int c ---> int constint z = 1; decltype(z) d = 2; // const int // 类型和表达式的类型是一致的
//decltype类型推导 int n = 100; decltype(func1()) a = 0; // int decltype(func2()) b = n; // int & decltype(func3()) c = 0; // int && decltype(func4()) d = 0; // int decltype(func5()) e = n; // const int & decltype(func6()) f = 0; // const int && decltype(func7()) g = Test(); // Test
func4() 返回的是一个纯右值(在表达式执行结束后不再存在的数据,也就是临时性的数据)
对于纯右值而言,只有 类类型可以携带 const、volatile 限定符
除此之外需要忽略掉这两个限定符,因此推导出的变量 d 的类型为 int 而不是 const int
1 2 3 4 5 6 7 8
// 类类型的 classTest { public: const Test func(){returnTest() }; };
Test t1, t2; decltype(t1.func()) p = t2; // const Test
intmain(){ const Test obj; decltype(obj.num) a = 0; // int decltype((obj.num)) b = a; // const int &
int n = 0, m = 0; decltype(n + m) c = 0; // int decltype(n = n + m) d = n; // int & return0; } // 第一个不加 const 原因和上面一致 // 第二个加 const 是因为 const Test obj,引用是根据规则,它有括号 // 疑惑点第三个和第一个也是左值,为啥不加引用 // 是因为规则的先后,它们更是一个普通变量类型,优先规则一 // 如果进行了加减乘除操作还赋值,就用第三个规则,如第四个案例
template <typename R, typename T, typename U> R add(T t, U u){ return t + u; }
intmain() { int x = 520; double y = 13.14; // auto z = add<decltype(x + y), int, double>(x, y); // 简化之后的写法 // 因为可以自动化推导出 x, y类型 auto z = add<decltype(x + y)>(x, y); cout << "z: " << z << endl; return0; } // 但是实际有问题,因为有可能这个函数模板提前封装起来了,不方便知道具体的返回值表达式 // 也就不能进行在外部进行 decltype 类型推导 // 在函数模板封装的时候就确定,外部用 auto 即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// 语法: // auto func(参数1, 参数2, ...) -> decltype(参数表达式)
template <typename T, typename U> // 返回类型后置语法 autoadd(T t, U u) -> decltype(t+u){ return t + u; }
intmain() { int x = 520; double y = 13.14; // auto z = add<int, double>(x, y); auto z = add(x, y); // 简化之后的写法 cout << "z: " << z << endl; return0; } // 这样即可实现,具体的 decltype 内的表达式看模板的具体逻辑