对象与基本类型(五)

91 阅读1分钟

类型别名与类型的自动推导

  • 可以为类型引入别名,从而引入特殊的含义或便于使用 (如: size_t)

  • 两种引入类型别名的方式

    • typedef int MyInt;
    • using MyInt = int;
  • 使用 using 引入类型别名更好

    • typedef char MyCharArr[4];
    • using MyCharArr = char[4];
  • 类型别名与指针、引用的关系

    • 应将指针类型别名视为一个整体,在此基础上引入常量表示指针为常量的类型
    • 不能通过类型别名构造引用的引用
using RefInt = int&;
using RefRefInt = RefInt&;

int main()
{
    // 1
    std::cout << std::is_same_v<RefInt, RefRefInt> << std::endl;
}
  • 类型的自动推导

    • 从 C++11 开始,可以通过初始化表达式自动推导对象类型

    • 自动推导类型并不意味着弱化类型,对象还是强类型

    • 自动推导的几种常见形式

      • auto: 最常用的形式,但会产生类型退化
      • const auto / constexpr auto: 推导出的是常量 / 常量表达式类型
      • auto&: 推导出引用类型,避免类型退化
      • decltype(exp): 返回 exp 表达式的类型(左值加引用)
      • decltype(val): 返回 val 的类型
      • decltype(auto): 从 c++14 开始支持,简化 decltype 使用
      • concept auto: 从 c++20 开始支持,表示一系列类型 (std::integral auto x = 3;)
#include <iostream>
#include <type_traits>

int main()
{
    int x1 = 3;
    int& ref = x1;
    const int y1 = 3;
    const int& y2 = y1;
    
    auto ref2 = ref; // int
    // 0
    std::cout << std::is_same_v<decltype(ref2), int&> << std::endl;
}
#include <iostream>
#include <type_traits>

int main()
{
    const int x = 3;
    auto y = x;  // int
    
    std::cout << std::is_same_v<decltype(y), int> << std::endl;  // 1
}
#include <iostream>
#include <type_traits>

int main()
{
    const int& x = 3;
    auto& y = x; // const int&
    std::cout << std::is_same_v<decltype(y), const int&> << std::endl; // 1
}
#include <iostream>
#include <type_traits>

int main()
{
    int x[3] = {1, 2, 3};
    auto& x1 = x;
    auto x2 = x;
    std::cout << std::is_same_v<decltype(x1), int(&)[3]> << std::endl; // 1
    std::cout << std::is_same_v<decltype(x2), int*> << std::endl; // 1
}
int main()
{
    decltype(3.5 + 15l) x = 3.5 + 15l;
}
int main()
{
    int x = 3;
    int& y1 = x;
    
    auto y2 = y1;               // int
    decltype(y1) y3 = y1;       // int&
}
int main()
{
    int x = 3;
    int* ptr = &x;

    std::cout << std::is_same_v<decltype(*ptr), int&> << std::endl; // 1
}
int main()
{
    int x = 3;
    int* ptr = &x;
    const int y1 = 3;
    const int& y2 = y1;
    
    // 1
    std::cout << std::is_same_v<decltype(3.5 + 15l), double> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype(*ptr), int&> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype(ptr), int*> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype(x), int> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype((x)), int&> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype(y1), const int> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype(y2), const int&> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype((y1)), const int&> << std::endl;
    // 1
    std::cout << std::is_same_v<decltype((y2)), const int&> << std::endl;
}
int main()
{
    decltype(auto) x = 3.5 + 15l;
}
#include <concepts>

int main()
{
    std::integral auto y = 3;
    // 1
    std::cout << std::is_same_v<decltype(y), int> << std::endl;
}