欢迎光临
我们一直在努力

【C++】五分钟带你了解C++系列(五):类型推导

什么是类型推导?

类型推导就是编译器帮助你自动将复杂的类型”猜出来“,从而不需要在代码里写冗长的类型名,主要涉及auto和decltype

类型推导解决了什么问题?

C++ 为了方便使用者,提供了类型推导的功能即auto和decltype,当一个变量带有复杂的修饰,如:

const int& ref = x;

或者是包含容器嵌套的类型:

std::map<std::string, std::vector<int>> myComplexMap;

还有就是从lambda中返回的复杂类型

auto add_lambda = [](int a, int b) -> int { return a + b; };

这种类型根本无法在代码里写出它的名字,因为它是由编译器随机生成的,比如 class <lambda_1d2a3b4c> 这种乱码

当我们需要处理这种类型的时候,就需要引入类型推导了。

auto vs decltype

auto

auto是一种只关心值的类型推导,并不保留引用与const/volatile等修饰符,而decltype精确保留着它们。

上面提到的例子:

int x 5;
const int& ref = x;

如果我们使用auto关键字获取类型,引用和const都被丢弃。

int x = 5;
const int& ref = x;

auto a = ref; // a 的类型是 int,而不是 const int&。
// 因为 auto 丢弃了引用和 const,变成了一个独立的 int 副本。
a = 10; // 合法,因为 a 只是 int,没有 const 限制

decltype

如果用decltype则精确保留了const和&

int x = 5;
const int& ref = x;

decltype(ref) d = x; // d 的类型是 const int&,完全复制了 ref 的类型。
d = 10; // 编译错误!因为 d 是 const 引用,不能修改。

完美转发的情况:同时使用

我们需要原封不动地获取一个函数的返回值时(比如完美转发std::forword的时候),需要保持精确,这样左右值引用才不会出现错配,但是一些参数的类型可能十分复杂,可以同时使用auto和decltype: 声明为decltype(auto)

// 场景:你写了一个转发函数,想原封不动地返回表达式结果(包括引用)
template<typename T>
decltype(auto) forward_example(T&& arg) {
return arg; // 如果 arg 是 int&,返回 int&;如果是 int&&,返回 int&&;完全保留
}

int x = 5;
forward_example(x) = 10; // 合法,因为返回的是 int&

赞(0)
未经允许不得转载:171主机测评 » 【C++】五分钟带你了解C++系列(五):类型推导
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址