题目

编写程序,深入测试 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