IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【SDU Chart Team - Core】SVG属性类设计之枚举 -> 正文阅读

[C++知识库]【SDU Chart Team - Core】SVG属性类设计之枚举

SVG属性类设计 (3)

需求

SVG属性类设计(1)中,定义了基本SVG属性类,提供了泛型的实现方式。接下来我们需要让SVG属性能进一步适配枚举型属性,例如"a|b"的类型要求。(具体的例子:rect元素中的cx,其合法属性为"<number>|<length>")。由于其性质和元组一致,称之为属性元组。

属性枚举的特点是包含多个不同的类型,且选取第一个非空合法类型值作为最终类型。

设计

属性枚举既有容器的性质又是属性,因此要包含泛型组件中的所有操作。

  • 底层容器

    仍然使用泛型容器std::tuple

  • 构造

    构造时遍历内部维护的_tuple,依次设置getter和setter为。

  • 提交与取值

    属性枚举虽然是容器,但其中的所有属性类型不能独立存在。提交时并不需要将各属性依次提交,只需获取缓冲区。

    遍历所有内部属性的提交区,最终的取值是第一个获取的非空值。

  • 赋值、绑定

    对所有内部属性分别操作即可。

细节

对于模板、参数展开等问题均在上一篇中说明,此处不再赘述。

  1. 函数静态类型转换

    绑定函数时发现存在静态转换问题,即:

    std::function<T()>
    

    (T*)()
    

    以及

    [](){ return T(); }
    

    在泛型下无法进行直接推导。

    最终考虑分开处理,对函数指针独立写一个新的泛型成员函数。但是lambda函数并没有好的解决方法。

  2. Lambda函数的静态类型转换

    1. 尝试一:static_cast

      手动进行静态类型转换,但是没法推导Lamdba函数的类型。了解到Lambda函数类型是编译器推导的一个函数对象(Functor),并不能直接获取

    2. 尝试二:decltype

      尝试用在static_cast基础上使用decltype对Lambda函数类型进行推导。随后发现C++11中不支持,高版本能支持。

    3. 最终解决方法:完全泛型+显式转换

      考虑重载一个泛型成员函数接受所有类型,然后尝试对该类型进行显式转换为std::function。

      具体的显式转换如下:

      namespace detail {
          template <typename F>
          struct function_traits : public function_traits<decltype(&F::operator())> {};
      
          template <typename R, typename C, typename... Args>
          struct function_traits<R (C::*)(Args...) const>
          {
              using function_type = std::function<R (Args...)>;
          };
      }
      
      namespace Lewzen {
          template <typename F>
          using function_type_t = typename detail::function_traits<F>::function_type;
      
          template <typename F>
          function_type_t<F> lambda_to_function(F & lambda) {
              return static_cast<function_type_t<F>>(lambda);
          }
      }
      

      先通过模板元编程,结合Lambda函数作为Functor的特性,利用其括号运算符重载,获取返回类型R、参数列表Args…,Lambda的原始类型C,进而协助进行静态类型转换为std::function。

  3. 返回只读类型的std::function作为参数的泛型函数重载问题

    测试中发现Lambda函数的返回类型并非只读,因此无法有限匹配到返回值只读作为参数的重载,造成递归无限循环。但理论上是能直接静态类型转换的。

    解决方法:另外创建一个函数,与返回值只读作为参数的重载参数列表相同,名称不同。强制Lambda对应的重载调用该函数。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:24:29  更:2022-04-26 11:28:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 22:54:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码