C++11 新特性:自动类型推导 auto 和 decltype(中)

今天我们来聊聊 decltype 关键字,它是 C++11 新增的一个关键字,和 auto 的功能一样,都是用来在编译时期进行自动类型推导。

decltype 是「declare type」的缩写,译为「声明类型」。

既然已经有了 auto 关键字,为什么还需要 decltype?

因为 auto 并不适用于所有的自动类型推导场景,在某些特殊情况下 auto 用起来非常不方便,甚至压根无法使用,所以引入了 decltype 关键字。

下面通过介绍 decltype 的用法,体会一下和 auto 的不同。

decltype 的用法

decltype 关键字用于检查实体的声明类型或表达式的类型,并且不会对表达式进行求值。

1、基本用法

decltype 可以直接用于变量,获取其类型。

cpp 复制代码
int x = 1;
decltype(x) y = x; // y 的类型为 int
decltype(10.8) z = 5.5; //z 的类型为 double
decltype(z + 100) a;  //a 的类型为 double

2、与复杂表达式一起使用

decltype 可以用于更复杂的表达式中。

cpp 复制代码
std::vector<int> v;
decltype(v.begin()) it = v.begin(); // it的类型为std::vector<int>::iterator

3、用于函数返回类型推导

在 C++11 及以后的版本中,decltype 可用于精确推导函数返回类型,尤其是当返回类型依赖于函数参数时。

cpp 复制代码
template<typename A, typename B>
auto add(A a, B b) -> decltype(a + b) {
    return a + b;
}

在这个例子中,函数 add 的返回类型通过 decltype 自动推导,这样函数就能够处理不同类型的参数,并返回正确的类型。

4、结合autodecltype用于自动类型推导

decltype还可以与auto结合使用,以便在需要类型匹配的场景中自动推导变量类型。

cpp 复制代码
auto x = 1;
decltype(auto) y = x; // y的类型为int

decltype 推导规则

上面的例子让我们初步感受了 decltype 的用法,但你不要认为 decltype 就这么简单,它的用法实际上可以非常复杂。

如果 decltype(exp) 中的表达式 exp,其类型为 T,那么:

  • 如果 exp 的值类型是 xvalue(将亡值),decltype 推导出的类型是 T&&;

  • 如果 exp 的值类型是 lvalue(左值),decltype 推导出的类型是 T&;

  • 如果 exp 的值类型是 prvalue(纯右值),decltype 推导出的类型是 T。

上面这三条规则有点抽象,不像人说的话,其中的「值类型」,在后面的文章中会详细解释。

当前只要记住下面这三条规则,就能应对 90% 的场景:

  • 如果 exp 是一个不被括号()包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,那么 decltype(exp) 的类型就和 exp 一致,这是最常见的情况。

  • 如果 exp 是函数调用,那么 decltype(exp) 的类型就和函数返回值的类型一致。

  • 如果 exp 是一个左值,或者被括号()包围,那么 decltype(exp) 的类型就是 exp 的引用;假设 exp 的类型为 T,那么 decltype(exp) 的类型就是 T&

代码示例

我们通过一个具体的例子来展示 decltype 的实际应用。

假设我们需要实现一个泛型函数,该函数能够根据传入参数的类型动态决定返回值的类型。

cpp 复制代码
#include <iostream>
#include <vector>

template<typename T>
auto multiply(T x, T y) -> decltype(x * y) {
    return x * y;
}

int main() {
    auto result1 = multiply(5, 4); // result1的类型为int
    std::cout << "int result: " << result1 << std::endl;

    auto result2 = multiply(3.14, 2.71); // result2的类型为double
    std::cout << "double result: " << result2 << std::endl;
}

在这个例子中,函数 multiply 能够根据传入参数的类型(无论是整型还是浮点型),通过 decltype 自动推导出正确的返回类型。这种类型推导不仅使代码更加灵活和通用,也保持了类型安全,避免了类型不匹配的错误。

decltype 提供了一种方式,来捕获表达式的类型,而不实际计算表达式的值。这在模板编程、泛型编程以及需要精确控制类型的场景中非常有用。结合 auto 关键字,decltype 为C++程序提供了更大的灵活性和表达能力。

相关推荐
AI街潜水的八角7 分钟前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
JSU_曾是此间年少37 分钟前
数据结构——线性表与链表
数据结构·c++·算法
此生只爱蛋2 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
何曾参静谧2 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
lulu_gh_yu3 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
ULTRA??3 小时前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
凌云行者4 小时前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
凌云行者4 小时前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
~yY…s<#>4 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
可均可可5 小时前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite