跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • Online Tools
  • 用户
  • 群组
折叠
品牌标识

D2Learn Forums

  1. 主页
  2. Open Courses | 公开课
  3. mcpp-standard | 动手学 - 现代C++核心语言特性
  4. C++11: 核心语言特性0: 类型自动推导 - auto和decltype

C++11: 核心语言特性0: 类型自动推导 - auto和decltype

已定时 已固定 已锁定 已移动 mcpp-standard | 动手学 - 现代C++核心语言特性
c++decltype类型c++语言特性mcpp-standard
2 帖子 1 发布者 172 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • SPeakS 离线
    SPeakS 离线
    SPeak d2learn-dev
    写于 最后由 SPeak 编辑
    #1

    auto 和 decltype 是C++11引入的强有力的类型自动推导工具. 不仅让代码变的更加简洁, 还增强了模板和泛型的表达能力

    Book Video Code X
    cppreference-auto / cppreference-decltype / markdown 视频解读 练习代码

    16x9.png

    为什么引入?

    • 解决类型声明过于复杂的问题
    • 模板应用中, 获取对象或表达式类型的需求
    • 为lambda表达式的定义做支撑

    auto和decltype有什么区别?

    • auto常常用于变量定义, 推导的类型可能丢失const或引用(可显示指定进行保留auto &)
    • decltype获取表达式的精确类型
    • auto通常无法作为模板类型参数使用

    一、基础用法和场景

    声明定义

    充当类型站位符, 辅助变量的定义或声明。使用auto时变量必须要初始化, decltype可以不用初始化

    int b = 2;
    auto b1 = b;
    decltype(b) b2 = b;
    decltype(b) b3; // 可以不用初始化
    

    表达式类型推导

    常常用于复杂表达式的类型推导, 确保计算精度

    int a = 1;
    
    auto b1 = a + 2;
    decltype(a + 2 + 1.1) b2 = a + 2 + 1.1;
    
    auto c1 = a + '0';
    decltype(2 + 'a') c2 = 2 + 'a';
    

    复杂类型推导

    迭代器类型推导

    std::vector<int> v = {1, 2, 3};
    
    auto it = v.begin(); // 自动推导it类型
    // decltype(v.begin()) it = v.begin();
    for (; it != v.end(); ++it) {
        std::cout << *it << " ";
    }
    

    函数类型推导

    对于函数或lambda表达式这种复杂类型, 常常使用auto和decltype. 一般, lambda定义用auto, 模板类型参数用decltype

    int add_func(int a, int b) {
        return a + b;
    }
    
    int main() {
        auto minus_func = [](int a, int b) { return a - b; };
    
        std::vector<std::function<decltype(add_func)>> funcVec = {
            add_func,
            minus_func
        };
    
        funcVec[0](1, 2);
        funcVec[1](1, 2);
        //...
    }
    

    函数返回值类型推导

    语法糖用法

    auto为后置返回类型函数定义写法做支持, 并可以配合decltype进行返回类型推导使用

    auto main() -> int {
        return 0;
    }
    
    auto add(int a, double b) -> decltype(a + b) {
        return a + b;
    }
    

    函数模板返回值类型推导

    当无法确定模板返回值时可以用auto + decltype做推导, 可以让add支持一般类型int, double,... 和 复杂类型 Point, Vec,... 增强泛型的表达能力. (c++14中可以省略decltype)

    template<typename T1, typename T2>
    auto add(T1 a, T2 b) -> decltype(a + b) {
        return a + b;
    }
    

    类/结构体成员类型推导

    struct Object {
        const int a;
        double b;
        Object() : a(1), b(2.0) { }
    };
    
    int main() {
        const Object obj;
    
        auto a = obj.a;
        std::vector<decltype(obj.b)> vec;
    }
    

    二、注意事项 - 括号带来的影响

    decltype(obj) 和 decltype( (obj) )的区别

    • 一般decltype(obj)获取的时其声明类型
    • 而decltype( (obj) ) 获取的是 (obj) 这个表达式的类型(左值表达式)
    int a = 1;
    decltype(a) b; // 推导结果为a的声明类型int 
    decltype( (a) ) c; // 推导结果为(a)这个左值表达式的类型 int & 
    

    decltype(obj.b) 和 decltype( (obj.b) )的区别

    • decltype( (obj.b) ): 从表达式视角做类型推导, obj定义类型会影响推导结果. 例如, 如果obj被const修饰时, const会限定obj.b的访问为const
    • decltype(obj.b): 由于推导的是成员声明类型, 所以不会受obj定义的影响
    struct Object {
        const int a;
        double b;
        Object() : a(1), b(2.0) { }
    };
    
    int main() {
        Object obj;
        const Object obj1;
    
        decltype(obj.b)  // double
        decltype(obj1.b) // double
    
        decltype( (obj.b) ) // double & 
        decltype( (obj1.b) ) // 受obj1定义的const修饰影响, 所以是 const double &
    }
    

    右值引用变量, 在表达式中是左值

    int &&b = 1;
    
    decltype(b) // 推导结果是声明类型 int &&
    decltype( (b) ) // 推导结果是 int &
    

    三、其他

    • 交流讨论
    • mcpp-standard教程仓库
    • 教程视频列表
    • 教程支持工具-xlings
    1 条回复 最后回复
    0
    • SPeakS 离线
      SPeakS 离线
      SPeak d2learn-dev
      写于 最后由 编辑
      #2

      https://en.cppreference.com/w/cpp/language/decltype

      image.png

      1 条回复 最后回复
      0
      • sunrisepeakS sunrisepeak 从 中的 General Discussion | 综合讨论 移动了该主题

      • 登录

      • 没有帐号? 注册

      • 登录或注册以进行搜索。
      d2learn forums Powered by NodeBB
      • 第一个帖子
        最后一个帖子
      0
      • 版块
      • 最新
      • 标签
      • 热门
      • Online Tools
      • 用户
      • 群组