traits编程基础

2024-03-07 18:32
文章标签 基础 编程 traits

本文主要是介绍traits编程基础,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

哈,我发现我终于成为标题党啦,全拿一些powerful的词做标题,骗点击率。说实话,在学校写论文全是有目的的,保研,升学,拿学位等,其实写的都是些什么哦,这里抄那里抄,能把专家组唬到就是好文章,写博客不同,我爱写就写,你当我是炫耀也好,轻浮也罢,都不放在耳边。

C++语言其实一点都不强大,强大的是那些使用C++的牛人们!

1,traits技法

这个说法我是从《STL源码剖析》中看到的,但是真正明白还是后来慢慢想才明白的。traits的意思是‘特性’,《Eff C++》里说将类的设计视为类型的设计,把class的设计当成type的设计,C++提供了一种无限的可能,使你可以不断的设计新的类型,从而使语言本身更强大。面对各种class,语言本身也没有提供太多的东西去描述‘特性’,有些知识是一开始不可预料的,所以没办法定义,比如,可拷贝性。如果语言定义一开始就很注重这个概念,那可能会多一个关键字操作符,譬如copiable()。在C的时代有sizeof(),在C++的时候有typeof,开玩笑,是typeid,但是这是在运行时,但是有了traits技法,这个是不必要的,将这些事情给编译器在编译期运行,会给运行程序带来更多的效率。我们知道型别本身这个信息也可以看成是基本的‘特性’。

在编译期做‘特性’检查,就是做类似这样的事情:

template<typename T>
void doSomething(T& t)
{
     if(t 具有某种特性)
    {
      做一些事情
    }
    else
    {
      做另一些事情
    }
}

在运行期做,可以这样设计T

class T
{
public:
   T() : copiable(true) {}
   virtual ~T() {}
    bool copiable;
};

这样做很糟糕,第一,‘特性’本身做为数据存储起来,那就会存在各个对象内,浪费空间,如果用静态数据,也很麻烦,第二,在doSomething()里要多做一次判断,浪费时间,浪费运行期时间。总之就是,浪费运行期的时间和空间。

将这些事移到编译期做,编译期能做些什么?类型推导。同时还需要C++一个本身的功能,就是偏特化。在运行期的数据、信息,我们转化为类型,用类来表示这些信息,比如特性。

首先,定义表示‘真’和‘假’的类:

struct _true_type{};
struct _false_type{};

它们对应于运行期的值,true和false;

再将特性定义成内嵌类型的typedef:

class T
{
   typedef _true_type copiable;
};

然后在doSomething()里做类型推导:

template<typename T>
void doSomething(T& t)
{
  typedef typename T::copiable copiable;
  doSomething_aux(t,copiable());
}

真正在推导的是另一个重载的函数doSomething_aux,如下定义

template<typename T>
void doSomething_aux(T& t,_true_type)
{
  当可以拷贝时做的事情
}

template<typename T>
void doSomething_aux(T& t,_false_type)
{
 当不可以拷贝时做的事情
}

这样就大功告成,似乎只用到了重载函数,但是这样的特性方法不能推广到基本类型,比如,T是int型,那在doSomething里就出错了,int::copiable没有定义,当然啦,你不可能把这个特性加进去。

再加一层封装可以解决这个问题:

template<typename T>
struct type_traits
{
  typedef T::copiable copiable;
};

然后改写doSomething:

template<typename T>
void doSomething(T& t)
{
  typedef typename type_traits<T>::copiable copiable;
  doSomething_aux(t,copiable());
}

为什么要转这么个弯?因为这样做了就有机会为基本类型添加特性信息,我们可以特化这个type_traits为基本类型,如

template<>
struct type_traits<int>
{
  typedef _true_type copiable;
};

STL里有个文件type_traits.h里面就定义了所有这些基本类型的偏特化版,当然,这里的copiable是我想出来的一个特性。

不仅仅只能为type可以定义traits,还可以为其它很多概念定义traits,比如iterator,它的偏特化版就牵扯到原始指针,可以认为,原始指针是一种iterator,而iterator是一个抽象的概念。

2,模板元编程TMP

traits技法是一种TMP,它是将一部分运行期运行的程序移到编译期,更大的挖掘编译器的能力,像上面那些对‘特性’的条件判断,就是利用了参数推导。而循环结构的程序,却是利用了递归,比如求fibonacci数的程序:

#include <cstdlib>
#include <iostream>

using namespace std;

template<unsigned int n>
struct fibonacci
{
       enum{value=fibonacci<n-1>::value+fibonacci<n-2>::value};
};

template<>
struct fibonacci<1>
{
       enum{value=1};
};

template<>
struct fibonacci<0>
{
       enum{value=0};
};
int main(int argc, char *argv[])
{
    cout<<fibonacci<10>::value<<endl;
    system("PAUSE");
    return EXIT_SUCCESS;
}

这相当于一个"hello TMP world"程序。更多的内容我还不了解,我只能感叹一句,这样的程序,真酷!

这篇关于traits编程基础的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/784431

相关文章

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We

AOP编程的基本概念与idea编辑器的配合体验过程

《AOP编程的基本概念与idea编辑器的配合体验过程》文章简要介绍了AOP基础概念,包括Before/Around通知、PointCut切入点、Advice通知体、JoinPoint连接点等,说明它们... 目录BeforeAroundAdvise — 通知PointCut — 切入点Acpect — 切面

从基础到高阶详解Python多态实战应用指南

《从基础到高阶详解Python多态实战应用指南》这篇文章主要从基础到高阶为大家详细介绍Python中多态的相关应用与技巧,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、多态的本质:python的“鸭子类型”哲学二、多态的三大实战场景场景1:数据处理管道——统一处理不同数据格式

C#异步编程ConfigureAwait的使用小结

《C#异步编程ConfigureAwait的使用小结》本文介绍了异步编程在GUI和服务器端应用的优势,详细的介绍了async和await的关键作用,通过实例解析了在UI线程正确使用await.Conf... 异步编程是并发的一种形式,它有两大好处:对于面向终端用户的GUI程序,提高了响应能力对于服务器端应

MySQL数据类型与表操作全指南( 从基础到高级实践)

《MySQL数据类型与表操作全指南(从基础到高级实践)》本文详解MySQL数据类型分类(数值、日期/时间、字符串)及表操作(创建、修改、维护),涵盖优化技巧如数据类型选择、备份、分区,强调规范设计与... 目录mysql数据类型详解数值类型日期时间类型字符串类型表操作全解析创建表修改表结构添加列修改列删除列