题目
编写程序,深入测试 auto 自动类型推导与 decltype 的类型捕获机制。演示 auto 在面对引用(&)和顶层常量(Top-level const)时发生的“类型退化”(Type Decay)现象;比对 auto、const auto& 与 decltype(...) 在推导表达式精确类型(保留引用与常量性)上的核心差异。
输入格式:无需外部输入。
输出格式:输出使用 std::is_same<T, U>::value 校验的类型推导判定布尔值。
数据范围与约定:C++11 类型推导系统与模板元编程基础。
思路与算法
1. auto 的推导退化规律
当使用 auto x = expr; 时,auto 的规则同函数模板按值传参:会忽略表达式的顶层 const 与引用修饰;若需保留引用必须显式写 auto&,需保留常量必须写 const auto。
2. decltype 的保真推导decltype(expr) 绝不发生退化,严格还原实体在声明时的精确类型(包括 const 和引用)。若 expr 是加了括号的左值表达式(如 decltype((x))),则推导为左值引用 T&。
3. decltype(auto) 现代应用
C++14 引入的 decltype(auto) 兼顾了 auto 的书写简洁性与 decltype 的零退化精准保真度,常用于高阶泛型转发。
完整程序
#include <iostream>
#include <type_traits>
int main() {
int x = 10;
const int cx = x;
const int& rx = x;
// 1. auto 推导退化
auto a1 = rx; // auto 退化为 int,丢失 const 和 &
a1 = 20; // 合法,修改 a1 不影响 x
std::cout << "auto a1 = rx 是否为 int: "
<< std::boolalpha << std::is_same<decltype(a1), int>::value << "\n";
std::cout << "修改 a1 后原变量 x: " << x << "\n\n";
// 2. 显式 auto& 保留修饰
auto& a2 = rx; // a2 推导为 const int&
std::cout << "auto& a2 = rx 是否为 const int&: "
<< std::is_same<decltype(a2), const int&>::value << "\n\n";
// 3. decltype 精确推导
decltype(rx) d1 = rx; // 严格推导为 const int&,必须初始化
std::cout << "decltype(rx) 是否严格为 const int&: "
<< std::is_same<decltype(d1), const int&>::value << "\n";
// 4. 双层括号表达式推导为引用
decltype((x)) d2 = x; // (x) 是左值表达式,推导为 int&
d2 = 99;
std::cout << "decltype((x)) 是否为 int&: "
<< std::is_same<decltype(d2), int&>::value << "\n";
std::cout << "通过 d2 修改后 x 的实际值: " << x << "\n";
return 0;
}运行示例
输出:
auto a1 = rx 是否为 int: true
修改 a1 后原变量 x: 10
auto& a2 = rx 是否为 const int&: true
decltype(rx) 是否严格为 const int&: true
decltype((x)) 是否为 int&: true
通过 d2 修改后 x 的实际值: 99