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

D2Learn Forums

SPeakS

SPeak

@SPeak
d2learn-dev
关于
帖子
174
主题
22
群组
1
粉丝
5
关注
0

帖子

最新 最佳 有争议的

  • 现代C++泛型编程初识 - 类模板到模板特例化及具体应用示例
    SPeakS SPeak

    文章导读

    • 一、类模板与模板特化(全特化与偏特化)
    • 二、类模板与其模板特化的应用
    • 三、模板特化存在性问题

    一、类模板与模板特化(全特化与偏特化)

    从接受类型的角度
    类模板:全集R
    模板偏特化(部分特化):为全集的一个子集A
    模板全特化:为R中的一个"点",或者说为R中的一个元素
    匹配规则:越特化匹配优先级越高(见下面例子)

    98a9da6a-01af-4fc4-83ad-91b7ca549699-image.png

    1.类模板

    可以接受任意类型

    // R
    template<typename T>
    class A {};    // 类模板是能接受任意类型,A后面不需要(不能)任何处理
    

    2.模板偏特化(局部特化)

    可以接受任意指针类型

    // A
    template<typename T>
    class A<T *> {};    // 类模板A的偏特化版本,在A后指出特化的范围
    

    3.模板全特化

    指定接受int类型

    template<>
    class A<int> {}    // 类模板A的全特化版本(已经是类模板的一个实例了),在A后直接指出明确类型int
    

    4.例子:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    template<typename T>
    class A {
    public:
        A() {
    	cout << "R" << endl;
        }
    };
    
    /* 注释1 -- 接受指针
    template<typename T>
    class A<T *> {
    public:
        A() {
    	cout << "A" << endl;
        }
    };
    */
    
    /* 注释2 -- 接受int
    template<>
    class A<int> {
    public:
        A() {
    	cout << "int" << endl;
        }
    };
    */
    
    int main() {
        A<string> r;    // 1
        A<char *> a;    // 2
        A<int> i;       // 3
        return 0;
    }
    

    5.测试不同情况:

    当只有一个类模板(可接受任意类型R)存在时,1, 2, 3都使用类模板实例化

    v2-a53836d6d2a913d69c2fd90b0dd4371f_1440w.png

    注释1是接受所以指针类型(R的子集A),所以称其为类模板A的偏特化(范围特化)。即把类模版A所能接受的指针类型单独处理(实例化)。当取消注释1时:char * 将由这个模板类A的偏特化版本(范围特化,局部特化)处理。

    v2-2bd02b7f6a4dbb5cdbc586f98d76b92b_1440w.png

    注释2只接受int类型的参数(可以看出是全局R中的一个元素)。当你用int实例化A时,将会由这个全特化版本来实现(而不会使用可以接受任意类型的版本(泛化版))。

    v2-6a08120bfe6da8471d8fb374b2665a65_1440w.png

    二、类模板与其模板特化的应用

    用模板的偏特化 实现一个 能移除任意类型const属性的模板类:remove_const
    主要功能和用法:
    功能:
    给remove_const一个类型后
    --1.(情况1)如果这个类型没有const属性则获得这个类型本身。
    --2.(情况2)如果这个类型有const属性则移除它。
    用法:
    remove_const<Type>::type
    使用场景:
    当拿到一个未知变量时,想获得这个变量(或对象)的非const的类型
    

    1.实现情况1

    似乎没做什么事,aa是int符合情况1。但情况2不符合,bb没有变成int。

    #include <iostream>
    #include <type_traits>
    
    template<typename T>
    struct remove_const {
        using type = T;
    };
    
    
    int main() {
        int a = 1;
        const int b = 2;
        remove_const<decltype(a)>::type aa = 3;
        remove_const<decltype(b)>::type bb = 4;
        std::cout << std::is_same<decltype(aa), int>::value << std::endl;
        std::cout << std::is_same<decltype(bb), int>::value << std::endl;
        return 0;
    }
    

    运行结果:
    v2-7a36de2df8473699ecc173f27351c876_1440w.png

    2.实现情况2

    从上面的实现可以看出,当传给模板的参数是带const类型时它还会返回带const属性的类型。同时从remove_const的定义也可以看出他是个 复读机 你给他什么类型他就给你什么类型。

    这时候可以使用上面介绍的偏特化的性质,来把带有带const的类型这个子集从全集中分离出来 特殊处理。如下:

    #include <iostream>
    #include <type_traits>
    
    template<typename T>
    struct remove_const {
        using type = T;
    };
    
    template<typename T>
    struct remove_const<const T> {
        using type = T;
    };
    
    int main() {
        int a = 1;
        const int b = 2;
        remove_const<decltype(a)>::type aa = 3;
        remove_const<decltype(b)>::type bb = 4;
        std::cout << std::is_same<decltype(aa), int>::value << std::endl;
        std::cout << std::is_same<decltype(bb), int>::value << std::endl;
        return 0;
    }
    

    运行结果:

    给带const的类型,写了一个特化版本。所以当remove_const接受一个带const的类型时,就会通过这个偏特化版本实例化,由于这个偏特化版本把const从类型中分离出来了,则这里的T就是没有const的类型,从而实现去除类型const的功能。

    v2-d337e4dc338fc9a90fcfa7ef9db27804_1440w.png

    三、模板特化存在性问题

    一个类模板的特化,是对某一个类模板的子集做特化处理的。而它不能"独立存在"。既只有存在一个类模板X, 才能存在对它特化的版本。

    template<typename T>
    class A<T *> {};
    
    int main() { return 0; }
    

    v2-1023f2d6ec20e5efa6300629068527d6_1440w.png


  • xlings install d2x:mcpp-standard报错
    SPeakS SPeak

    xlings安装的时候是再windows下安装的, 还是wsl下安装的啊。安装和使用要一致 (如果再wsl下使用需要安装linux版本

    包名找不到, 可以运行xim --update index 然后再试一试呢 如果还没有 可以运行 xim -s d2x 把搜索的结果贴到下面一下


  • xlings 安装失败,git网络问题 - [xlings:xim] main: error - Cloning into 'xim-pkgindex'... remote: [session-ac42ac85] reject by mode [ja-p] The requested URL returned error: 400
    SPeakS SPeak

    @saul-goodman-lja 嗯嗯, 可能是gitee网络服务的问题


  • xlings 安装失败,git网络问题 - [xlings:xim] main: error - Cloning into 'xim-pkgindex'... remote: [session-ac42ac85] reject by mode [ja-p] The requested URL returned error: 400
    SPeakS SPeak

    git clone https://gitee.com/sunrisepeak/xim-pkgindex.git

    感觉好像是被拦截了 手动用上面命令测试一下网络 看看有没有问题


  • xlings安装问题
    SPeakS SPeak

    @xuxubaobao 按下面尝试删除旧版本xlings 然后重新安装,
    把安装过程的log贴一下 我分析下什么原因

    • http://forum.d2learn.org/post/663

  • 问问大家写CPP项目使用的规范
    SPeakS SPeak

    如果作为一个库设计者的话, 感觉总体遵守

    • 接口易用性优先 (底层实现可以复杂, 但接口要尽可能的易用和理解
    • 区分内部接口和外部接口, 最小集合暴露给使用者

    谷歌有个C++风格指导: https://google.github.io/styleguide/cppguide.html


    在了解到一个项目如何架构和设计后, 又要回到现实 - 根据当下情况和目标, 对项目做出合适的架构, 而不要过渡设计, 因为每个项目都有他发展的时间段, 每个时期, 目标不同

    例如: 对于要快速能用或上线的MVP, 目标是能用就行, 反而没有太多设计就是好的设计


  • xlings 安装失败
    SPeakS SPeak

    @maoapoot 还记得第一安装为什么失败吗?网络原因之类的吗 还是 安装一半的 时候 中断了啊


  • xlings 安装失败
    SPeakS SPeak

    可以先手动删除旧版本xlings

    rm -rf /home/xlings
    

    然后重新运行安装命令 看行不行


  • xlings安装问题
    SPeakS SPeak

    source 一下 或者重新 打开一下终端刷新一下环境变量呢


  • 08-literal-type-0中遇到“non-constexpr function 'operator[]' cannot be used in a constant expression”
    SPeakS SPeak

    修复已合入, 可以更新到最新代码再尝试

    • https://github.com/Sunrisepeak/mcpp-standard/commit/d54dc1d240dc65ed52df1603e732dfc0e527c564

  • 08-literal-type-0中遇到“non-constexpr function 'operator[]' cannot be used in a constant expression”
    SPeakS SPeak

    从报错看 可能是clang的array下标操作符constexpr化实现 要求是14标准

    image.png

    • https://github.com/llvm/llvm-project/blob/06fc87bcd3d61a08f8c035e60949631f61bccee7/libcxx/include/array#L61

    目前我先给这个练习 指定一下标准, 后面有时间优化一下 练习代码


  • dsx自动检测出现错误
    SPeakS SPeak

    @dustchens 链表结构损坏, 不闭环了 (如果问题解决可以把帖子状态设置为已解决


  • dsx自动检测出现错误
    SPeakS SPeak

    @dustchens 通过分析, 发现主要是程序中存在死循环, 导致程序卡死

    • 死循环位置: 链表析构
    • 原因: 对象拷贝语义未实现 (练习要求实现的
    • 解决方法: 在分配器释放时, 如果异常立即退出程序, 避免crash导致检测中断

    具体改动: https://github.com/d2learn/d2ds/commit/92275563edf26c1c413f50fa1b0fc542d94e24ec

    尝试更新d2ds代码, 然后测试下是否还有这个问题


  • dsx自动检测出现错误
    SPeakS SPeak

    @dustchens 按你这样描述可能问题时 slist.2.cpp, 你可以试一试把这个里面只留一个D2X_WAIT看看呢, 然后你给一下你仓库的链接 我这里也测试一下

    测试前运行一下下面命令更新一下, 就直接用d2x checker 就可以了(不用手动到.xlings运行

    xlings self update
    

  • dsx自动检测出现错误
    SPeakS SPeak

    另外d2ds的最新版本, 下面的乱码应该没有了吧

    image.png


  • dsx自动检测出现错误
    SPeakS SPeak

    @dustchens 麻烦做以下两个验证

    1.在.xlings目录运行报错命令看是否也会报错(如果报错把报错贴一下报错信息

    cd .xlings
    xmake xlings -D --project=. J:\cpp_project\d2ds d2x checker
    

    2.先删除slist.1.cpp中main函数中的其他代码(只保留D2X_WAIT), 然后看是否会报错

    cd .xlings
    xmake xlings -D --project=. J:\cpp_project\d2ds d2x checker
    

    3.把百分百可以复现问题的代码提交到你fork的仓库, 并贴一下链接 我也尝试测试一下


  • dsx自动检测出现错误
    SPeakS SPeak

    可能是msvc构建的时候卡住了. 这个问题是必现, 还是偶现啊


    尝试更新d2ds最新代码, 然后使用xlings安装mingw工具链看是否能解决

    • 1.更新d2ds到最新的代码
    • 2.安装mingw/gcc
     xim --update index
     xlings install mingw-w64
    
    • 3.重新测试验证d2x checker

    https://github.com/d2learn/d2ds/commit/f7de9275b958d72267cece7d1055729985501c34


  • 安装mcpp-standard时创建多级目录, 路径中包含空格时, 导致项目文件打开无代码
    SPeakS SPeak

    xlings工具已增加支持对空格路径的支持

    • 具体改动: https://github.com/d2learn/xlings/commit/2d80a98cbd90c3549211672554bff08ae90fa7ac

    测试1 2空格路径截图

    image.png

    image.png


  • 安装mcpp-standard时创建多级目录, 路径中包含空格时, 导致项目文件打开无代码
    SPeakS SPeak

    todo

    • 相关问题: https://forum.d2learn.org/topic/142

  • 终端使用xlings checker不显示代码 - 自动打开的是空文件以及检测没有实时更新
    SPeakS SPeak

    补充: 检测终端没有实时更新问题解决方法

    • 方法1: 修改代码后手动(ctrl + s)保存文件, 检测程序即可自动检测到
    • 方法2: 设置vscode自动保

    image.png

  • 登录

  • 没有帐号? 注册

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