Type Inference in C++ (auto and decltype)
类型推断是指在编程语言中自动推断出表达式的数据类型。在 C++ 11 之前,每种数据类型都需要在编译时显式声明,从而在运行时限制表达式的值,但在 C++ 新版本之后,包含了许多关键字,允许程序员将类型推导留给编译器本身.
借助类型推断功能,我们可以减少编写编译器已经知道的东西的时间。由于所有类型都是在编译阶段推导出来的,编译时间略有增加,但不影响程序的运行时间。
1) auto 关键字: auto 关键字指定将被声明的变量的类型将自动从其初始化程序中扣除。在函数的情况下,如果它们的返回类型是自动的,那么它将在运行时由返回类型表达式进行评估。使用 auto 是为了避免在为容器创建迭代器时进行长时间的初始化。
注意:使用 auto 关键字声明的变量只能在声明时初始化,否则会出现编译时错误。
// C++ program to demonstrate working of auto
// and type inference
#include <bits/stdc++.h>
using namespace std;
int main()
{
// auto a; this line will give error
// because 'a' is not initialized at
// the time of declaration
// a=33;
// see here x ,y,ptr are
// initialised at the time of
// declaration hence there is
// no error in them
auto x = 4;
auto y = 3.37;
auto ptr = &x;
cout << typeid(x).name() << endl
<< typeid(y).name() << endl
<< typeid(ptr).name() << endl;
return 0;
}
输出
i d Pi
注意:我们使用typeid来获取变量的类型。
Typeid是一个运算符,用于需要知道对象的动态类型的情况。
typeid(x).name() 返回x的数据类型,例如,它返回’i’表示整数,’d’表示双精度数,’Pi’表示整数指针等。但实际返回的名称主要是编译器依赖。
使用 auto 是为了避免在为容器创建迭代器时进行长时间的初始化。
// C++ program to demonstrate that we can use auto to
// save time when creating iterators
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Create a set of strings
set<string> st;
st.insert({ "geeks", "for", "geeks", "org" });
// 'it' evaluates to iterator to set of string
// type automatically
for (auto it = st.begin(); it != st.end(); it++)
cout << *it << " ";
return 0;
}
输出
for geeks org
注意:即使分配了整数引用, auto 也会变成 int 类型。为了使其成为引用类型,我们使用 auto &。
- 返回“对 int 的引用”类型的函数:int& fun() {};
- m 将默认为 int 类型而不是 int& 类型: auto m = fun();
- n 将是 int& 类型,因为使用了额外的 & 和 auto 关键字: auto& n = fun();
2) decltype 关键字:它检查实体的声明类型或表达式的类型。’auto’ 允许您声明具有特定类型的变量,而 decltype 允许您从变量中提取类型,因此 decltype 是一种计算传递表达式类型的运算符。
上述关键字及其用途的解释如下:
// C++ program to demonstrate use of decltype
#include <bits/stdc++.h>
using namespace std;
int fun1() { return 10; }
char fun2() { return 'g'; }
int main()
{
// Data type of x is same as return type of fun1()
// and type of y is same as return type of fun2()
decltype(fun1()) x;
decltype(fun2()) y;
cout << typeid(x).name() << endl;
cout << typeid(y).name() << endl;
return 0;
}
输出
i c
下面是另一个示例来演示decltype的使用,
// C++ program to demonstrate use of decltype
#include <bits/stdc++.h>
using namespace std;
// Driver Code
int main()
{
int x = 5;
// j will be of type int : data type of x
decltype(x) j = x + 5;
cout << typeid(j).name();
return 0;
}
输出
i
一个演示 auto 和 decltype 使用的程序
下面是一个C++ 模板函数min_type(),它返回两个数字中的最小值。这两个数字可以是任何整数类型。返回类型是使用最少两个的类型来确定的。
// C++ program to demonstrate use of decltype in functions
#include <bits/stdc++.h>
using namespace std;
// A generic function which finds minimum of two values
// return type is type of variable which is minimum
template <class A, class B>
auto findMin(A a, B b) -> decltype(a < b ? a : b)
{
return (a < b) ? a : b;
}
// driver function to test various inference
int main()
{
// This call returns 3.44 of double type
cout << findMin(4, 3.44) << endl;
// This call returns 3 of double type
cout << findMin(5.4, 3) << endl;
return 0;
}
输出
3.44 3
decltype 与 typeid
- Decltype 在编译时给出类型信息,而 typeid 在运行时给出。
- 因此,如果我们有一个引用(或指向)派生类对象的基类引用(或指针),decltype 会将类型作为基类引用(或指针)给出,但 typeid 将给出派生类型引用(或指针) .