突破编程_C++_C++11新特性(type_traits的概念以及核心类型特性)

1 type_traits 的概述

type_traits 是 C++ 标准模板库(STL)中的一个头文件,它定义了一系列模板类,这些模板类在编译期获取某一参数、某一变量、某一个类等的类型信息,主要用于进行静态检查。通过使用 type_traits,程序员可以在编译时就获得关于类型的详细信息,从而可以在不实际运行程序的情况下进行类型相关的优化和检查。

type_traits 中的内容主要可以分为以下几类:

  • 辅助基类:如 std::integral_constant 以及其特化 true_type 和 false_type,这些类用于创建编译器常量,同时也是类型萃取类模板的基类。
  • 类型萃取类模板:这些模板类用于在编译期以常量的形式获取类型特征。例如,std::is_integral 用于检查一个类型是否为整数类型,std::is_floating_point 用于检查一个类型是否为浮点类型,std::is_base_of 用于检查一个类型是否是另一个类型的基类等。这些模板类主要用来进行类型属性的判断。
  • 类型转换类模板:这些模板类用于通过执行特定操作从已有类型获得新类型。例如,std::add_const 用于给类型添加 const 限定符,std::remove_volatile 用于移除类型的 volatile 限定符等。

type_traits 的主要作用包括:

  • 在编译期对类型进行属性检查和转换,避免了运行时的类型检查和转换开销。
  • 使得模板编程更加灵活和安全,可以在模板实例化之前根据类型属性选择不同的实现。
  • 为 STL 中的算法和容器提供了类型相关的支持,例如,STL 中的算法通过迭代器存取容器内容,而 type_traits 可以协助算法根据迭代器类型或容器类型选择不同的策略。

在 C++11 给出 type_traits 之前,对于类型处理有很多非常不方便的地方:

(1)类型信息的缺失: C++ 是一种静态类型语言,这意味着在编译时,每个变量和表达式都必须有明确的类型。然而,标准 C++ 并没有提供一个直接的机制来获取和操作这些类型信息。在没有 type_traits 的情况下,程序员通常需要手动跟踪和处理类型信息,这既繁琐又容易出错。

(2)模板元编程的复杂性: C++ 的模板元编程是一种在编译期进行计算和类型操作的技术。然而,由于缺乏 type_traits 这样的工具,模板元编程变得异常复杂和难以维护。程序员需要手动编写大量的模板特化和递归代码,以处理各种类型情况。这不仅增加了开发难度,也降低了代码的可读性和可维护性。

(13)类型安全和泛型编程的限制: 在泛型编程中,我们通常需要编写能够处理多种类型的代码。然而,在没有 type_traits 的情况下,我们很难在编译期对类型进行严格的检查和约束。这可能导致类型不安全的代码,例如,错误地将一个浮点数传递给期望整数的函数。此外,由于缺乏类型萃取和转换的工具,泛型编程的灵活性也会受到限制。

(4)性能优化的挑战: 在某些情况下,我们需要根据类型信息来优化代码的性能。例如,对于某些特定的类型,我们可能希望使用特定的算法或数据结构。然而,在没有 type_traits 的情况下,这种优化变得非常困难。我们需要编写复杂的条件编译代码,或者使用运行时类型信息(RTTI)来动态地选择实现。这些方法要么增加了编译的复杂性,要么引入了额外的运行时开销。

type_traits 的出现极大地缓解了这些挑战。它提供了一套丰富的工具,使得程序员可以在编译期获取和操作类型信息,从而简化了模板元编程,提高了类型安全性,并使得性能优化变得更加容易。通过使用 type_traits,可以编写更加灵活、安全和高效的 C++ 代码。

2 type_traits 核心类型特性

2.1 std::is_same

std::is_same 是一个模板类,用于检查两个类型是否相同。其定义如下:

template< class T, class U >  
struct is_same;

当 T 和 U 指名同一类型(考虑 const 和 volatile 限定)时,is_same<T, U>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha; // 输出 true 或 false 而不是 1 或 0  
    std::cout << "int and int are " << std::is_same<int, int>::value << '\n'; // 输出 true  
    std::cout << "int and float are " << std::is_same<int, float>::value << '\n'; // 输出 false  
    return 0;  
}

2.2 std::is_integral

std::is_integral 是一个模板类,用于检查一个类型是否为整数类型。其定义如下:

template< class T >  
struct is_integral;

当 T 为整数类型时,is_integral<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha;  
    std::cout << "int is " << std::is_integral<int>::value << '\n'; // 输出 true  
    std::cout << "double is " << std::is_integral<double>::value << '\n'; // 输出 false  
    return 0;  
}

2.3 std::is_floating_point

std::is_floating_point 是一个模板类,用于检查一个类型是否为浮点类型。其定义如下:

template< class T >  
struct is_floating_point;

当 T 为 float、double 或 long double(包括任何 cv 限定变体)时,is_floating_point<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha;  
    std::cout << "float is " << std::is_floating_point<float>::value << '\n'; // 输出 true  
    std::cout << "int is " << std::is_floating_point<int>::value << '\n'; // 输出 false  
    return 0;  
}

2.4 std::is_array

std::is_array 是一个模板类,用于检查一个类型是否为数组类型。其定义如下:

template< class T >  
struct is_array;

当 T 为数组类型时,is_array<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha;  
    std::cout << "int[5] is " << std::is_array<int[5]>::value << '\n'; // 输出 true  
    std::cout << "int is " << std::is_array<int>::value << '\n'; // 输出 false  
    return 0;  
}

2.5 std::is_pointer

std::is_pointer 是一个模板类,用于检查一个类型是否为指针类型。其定义如下:

template< class T >  
struct is_pointer;

当 T 为指针类型时,is_pointer<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  

int main() {
	std::cout << std::boolalpha;
	std::cout << "int* is " << std::is_pointer<int*>::value << '\n'; // 输出 true  
	std::cout << "int is " << std::is_pointer<int>::value << '\n'; // 输出 false  
	return 0;
}

2.6 std::is_reference

std::is_reference 是一个模板类,用于检查一个类型是否为引用类型。其定义如下:

template< class T >  
struct is_reference;

当 T 为引用类型时,is_reference<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha;  
    std::cout << "int& is " << std::is_reference<int&>::value << '\n'; // 输出 true  
    std::cout << "int is " << std::is_reference<int>::value << '\n'; // 输出 false  
    return 0;  
}

2.7 std::is_void

std::is_void 是一个模板类,用于检查一个类型是否为 void 类型。其定义如下:

template< class T >  
struct is_void;

当 T 为 void 类型时,is_void<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha;  
    std::cout << "void is " << std::is_void<void>::value << '\n'; // 输出 true  
    std::cout << "int is " << std::is_void<int>::value << '\n'; // 输出 false  
    return 0;  
}

2.8 std::is_const

std::is_const 是一个模板类,用于检查一个类型是否为常量类型。其定义如下:

template< class T >  
struct is_const;

当 T 为常量类型时,is_const<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha;  
    std::cout << "const int is " << std::is_const<const int>::value << '\n'; // 输出 true  
    std::cout << "int is " << std::is_const<int>::value << '\n'; // 输出 false  
    return 0;  
}

2.9 std::is_volatile

std::is_volatile 是一个模板类,用于检查一个类型是否为易变类型。其定义如下:

template< class T >  
struct is_volatile;

当 T 为易变类型时,is_volatile<T>::value 为 true,否则为 false。

样例:

#include <iostream>  
#include <type_traits>  
  
int main() {  
    std::cout << std::boolalpha;  
    std::cout << "volatile int is " << std::is_volatile<volatile int>::value << '\n'; // 输出 true  
    std::cout << "int is " << std::is_volatile<int>::value << '\n'; // 输出 false  
    return 0;  
}

2.10 其他类型

除了上面介绍的类型,type_traits 还有如 std::is_signed (检查类型是否有符号)、std::is_unsigned (检查类型是否无符号)、std::is_arithmetic ( 检查类型是否为算术类型(整数或浮点数))等基础核心类型,具体的可以查看 C++ 标准中的类型说明。也可以通过查看头文件 <type_traits> 获得。

3 使用核心类型特性实现泛型编程中的条件编译

在 C++11 中,可以使用模板特化或者 std::enable_if 来实现类似条件编译的效果。下面是一个使用 std::is_same 和 std::is_integral 以及 std::enable_if 来实现泛型编程中条件编译的实例:

#include <iostream>  
#include <type_traits>  

// 泛型函数模板,用于非整数类型  
template<typename T, typename = void>
void print_type_info(T value, typename std::enable_if<!std::is_integral<T>::value>::type* = nullptr) {
	std::cout << "Value is of a non-integral type." << std::endl;
}

// 对 int 类型特化的版本  
template<typename T>
void print_type_info(T value, typename std::enable_if<std::is_same<T, int>::value>::type* = nullptr) {
	std::cout << "Value is of type int with value: " << value << std::endl;
}

// 对整数类型特化的版本,但排除 int  
template<typename T>
void print_type_info(T value, typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, int>::value>::type* = nullptr) {
	std::cout << "Value is of an integral type (non-int) with value: " << value << std::endl;
}

int main() {
	// 调用 print_type_info 模板函数,传入不同类型的值  
	print_type_info(12); // 调用 int 特化的版本  
	print_type_info(3.14f); // 调用非整数类型特化版本  
	print_type_info(static_cast<long long>(1234567890123456789)); // 调用整数类型特化的版本(排除 int)  
	return 0;
}

上面代码的输出为:

Value is of type int with value: 12
Value is of a non-integral type.
Value is of an integral type (non-int) with value: 1234567890123456789

这个例子定义了三个版本的 print_type_info 函数模板:

  • 一个非特化的版本,它接受非整数类型的参数 T,并打印一个通用消息。
  • 一个对 int 类型特化的版本,它只接受 int 类型的参数,并打印 int 类型的特定消息。
  • 一个对整数类型(除了 int)特化的版本,它接受任何整数类型(除了 int)的参数,并打印整数类型的特定消息。

std::enable_if 用于在编译时启用或禁用模板函数的不同特化版本。std::enable_if 的第二个模板参数是一个类型,当该类型存在时,模板会被启用;当该类型为 void 时,模板会被禁用。std::is_same<T, int>::value 和 std::is_integral<T>::value 用于在编译时检查类型。

4 使用核心类型特性实现类型安全的容器

下面是一个简单的类型安全整数容器的例子,它只允许存储整数类型,并且可以使用 std::is_same 来确保不添加与容器定义类型相同的类型:

#include <iostream>  
#include <type_traits>  
#include <vector>  
#include <stdexcept>  

// 类型安全的整数容器  
template<typename T>
class TypeSafeIntegerContainer {
public:
	static_assert(std::is_integral<T>::value, "TypeSafeIntegerContainer can only hold integral types.");

	// 添加元素到容器中  
	template<typename U, typename = std::enable_if<std::is_integral<U>::value && !std::is_same<U, T>::value>>
	void add(U value) {
		// 检查新类型是否与 T 类型相同  
		static_assert(!std::is_same<U, T>::value, "Cannot add the same type to the container.");
		data.push_back(static_cast<T>(value));
	}

	// 获取容器中所有元素的数量  
	size_t size() const {
		return data.size();
	}

	// 打印容器中所有元素的值  
	void print() const {
		for (const auto& elem : data) {
			std::cout << elem << " ";
		}
		std::cout << std::endl;
	}

private:
	std::vector<T> data; // 存储整数类型的容器  
};

int main() 
{
	TypeSafeIntegerContainer<int> intContainer;

	// 添加不同类型的整数到容器中  
	intContainer.add(10L); // OK, long is converted to int  
	intContainer.add(20LL); // OK, long long is converted to int  
	intContainer.add(30U); // OK, unsigned int is converted to int  

	// 尝试添加相同类型的整数会导致编译错误  
	// intContainer.add(40); // 编译错误: Cannot add the same type to the container.  

	// 打印容器中的元素  
	intContainer.print(); // 输出: 10 20 30   

	// 尝试创建一个存储非整数类型的容器会导致编译错误  
	// TypeSafeIntegerContainer<std::string> stringContainer; // 编译错误: TypeSafeIntegerContainer can only hold integral types.  

	return 0;
}

上面代码的输出为:

10 20 30

在这个例子中,TypeSafeIntegerContainer 是一个模板类,它接受一个整数类型 T 作为模板参数。它有一个 add 成员函数模板,该函数模板只接受与 T 不同且为整数类型的参数。样例使用 std::enable_if_t 和 std::is_integral 来确保这一点。

这个例子还使用 static_assert 来确保在实例化 TypeSafeIntegerContainer 时,T 是一个整数类型,以及在调用 add 方法时,新类型 U 不与 T 相同。如果尝试添加与 T 类型相同的类型,或者尝试存储非整数类型,都会导致编译错误。

  • 16
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
新手编程导论 ———— A Programming Introduction For Beginners By Minlearn @ http://www.actyou.com.cn/ 设计才是真正的编程! 对类型的设计才是设计! 面向对象并非一切? 无论你以为上述观点是惊天大秘或不过尔尔,你都需要这本书! -------------------------------------------------------------------------------------------------------------- Todo: 整合过长的目录 完善前二十页 -------------------------------------------------------------------------------------------------------------- 目 录 第一部分 9 前 言 9 By Chenyi 9 By Minlearn 10 导 读 14 任何语言都是有门槛的 14 什么是语言级和语言外要学习的(数据结构与代码结构) 15 什么是语言级要学习的 17 编程学习方法 18 计算机学生专业课程本质讲解 18 用C++开发要学到什么程度 20 本书目录安排 21 第二部分 基础:导论 25 第1章 系统 25 1.1 何谓PC 25 1.2 图灵机与冯氏架构 26 1.3计算机能干什么 27 1.4 内存地址 28 1.5 分段和分页以及保护模式 30 1.7 操作系统 31 1.6 并发与协程 33 1.6 CPU与异常 33 1.7 所谓堆栈 34 1.8 真正的保护模式 36 1.9 异常与流转 38 1.10 最小,最完美的系统 39 1.11 操作系统与语言的关系 41 1.12 虚拟机与语言 41 1.13 虚拟机与语言 42 1.14 调试器与汇编器 43 1.15 平台之GUI 45 1.16 界面的本质应该是命令行功能支持下的配置描述文件 45 1.17 命令行下编程实践 46 第2章 语言 47 2.1 真正的计算模型 47 2.2 开发模型与语言模型 49 2.3 正规表达式与有限自动机 53 2.4 联系编译原理学语言 56 2.6 如何理解运行时 59 2.7 运行时环境 60 2.7 运行时 60 6.3 语言类型系统 60 2.8 编译与解释 62 2.9 运行期与编译期 62 2.9 编译与运行期分开的本质与抽象 63 2.10 脚本语言 63 2.11 灵活性与安全性 65 2.12 二进制指令与循环 66 2.13 所谓函数 67 2.14 所谓流程 68 2.15 为什么需要数据类型和数据结构 68 2.16 数据类型和数据结构是二种不一样的东西 69 2.17 为什么需要变量这些东东 69 2.18 面向类型化的设计和面向无类型泛化的设计-OO不是银弹 70 第3章 语言之争 71 3.1 学编程之初,语言之争 71 3.2 语言与应用与人(1) 72 3.2 语言与应用与人(2) 73 3.3 C与Ruby 74 3.4 你为什么需要Ruby 75 3.5 C++还是Ruby 76 3.6 C++与Java 76 3.7 .NET与JVM 77 3.8 你为什么需要Ruby 78 3.9 语言功能上的差别 79 3.10 C与C++之争 80 3.11 我为什么选择C而不是C++及其它语言 81 3.12 类VB,DELPHI类RAD语言分析 82 第4章 语言最小内核(C) 83 4.1 C与C++是二种不同的语言 83 4.2 C的数组,指针与字符串 84 4.3 C的输入与输出流 84 4.4 C的类型系统与表达式 85 4.5 二进制指令看循环 85 4.6 所谓指针:当指针用于设计居多时 86 4.7 指针成就的C语言 86 4.8 指针是语言的一种抽象机制 88 4.9 学C千万不能走入的一个误区(其实JAVA比C难) 88 4.10 C抽象惯用法 90 4.11 C的抽象范式之OOP 91 4.12 C的观点:底层不需要直接抽象 93 4.13 指针:间接操作者 94 4.14 真正的typedef 95 4.15 真正的指针类型 95 4.16 真正的函数指针 97 4.17 真正的句柄 97 4.18 真正的循环 98 4.19 真正的static 98 4.20 真正的数组索引 99 4.21 类型和屏看原理 100 4.22 位操作与多维数组指针与元素 101 4.23 变量与VOID 102 第5章 抽象 102 5.1 人与软件 103 5.2 软件活动的特点 103 5.2 抽象与接口 104 5.3 过度抽象 105 5.3 OO为什么不是银弹 - 过度抽象与抽象偏差 106 5.4 真正的设计与编码 107 5.5 真正的构件库 109 5.6 大逻辑与小逻辑 112 5.7 什么是范式 112 第6章 抽象之数据结构 113 6.1 所谓数据结构 113 6.2 算法+数据结构的本质 115 6.4 算法不是设计 115 6.5 函数增长与算法复杂性分析 115 6.6 数据结构初步引象(1) 116 6.7 数据结构初步引象(2) 117 6.8 数据结构初步引象(3) 118 6.9 数据结构初步引象(4) 119 6.10 ordered与sorted 119 6.11 数据结构与抽象 119 6.12 真正的逻辑数据结构只有二种 120 6.12 树与图初步引象 121 6.13 树初步引象 122 6.14 B减树 123 6.15 图初步引象 124 6.16 树的平衡与旋转 125 6.17 完全与满 129 6.18 多路234树与红黑树的导出 129 6.19 快速排序思想 130 6.20 数据结构之数组 131 6.21 数据结构的抽象名字 132 6.22 真正的ADT 133 6.23 Vector的观点 135 6.24 真正的数据结构 136 6.25 堆栈与队列 138 6.26 真正的递归 140 6.27 树与单链表,图 145 6.28 树 146 6.29 真正的散列表 148 6.30 算法设计方法 148 第7章 抽象之高级语法机制 149 7.1 真正的OO解 149 7.2真正的对象 151 7.3真正的继承 152 7.4真正的OO 152 7.5真正的OOP 154 7.6 真正的构造函数 155 7.7 真正的私有,保护和公有 156 7.8 真正的重载与复写 156 7.9 C++的元编程 156 7.10 模板的意义在于编译前端的设计 157 7.11 C++的元编程和泛型编程 159 7.12 元编程和函数式编程 159 7.13 C++的模板编译技术本质 161 7.14 OO的缺点 161 7.15 模板的继承 162 7.16 模板的偏特化 162 7.17 真正的策略 162 7.18 为设计产生代码 164 7.19 真正的metaprogramming 165 7.20 元编程技术 166 第8章 抽象之设计和领域逻辑 167 8.1 大设计 167 8.1 什么是设计 167 8.2 编程能力,代码控制能力,复用与接口,轮子发明与使用 170 8.3 OO,模板,设计模式与设计 171 8.4 设计能力和程序员能力模型 172 8.4 自上而下设计和自下而上设计 173 8.5 大中型软件和复用与逻辑达成 177 8.6 通用设计与专门设计 178 8.7 具象与抽象 178 8.7 架构与应用 179 8.8 应用与设计 179 8.9 与软件有关的哲学 联系 180 8.10 与软工有关的哲学 唯物主义 180 8.11 真正的设计模式 182 8.12 设计模式与数据结构 182 8.12 设计模式之基础 183 8.12 真正的开闭原则 183 8.13 真正的通米特原则 184 8.14 真正的好莱钨原则 185 8.15 真正的策略模式 185 8.16 真正的观察者模式 185 8.17 真正的装饰模式 186 8.18 真正的单例模式 186 8.19 真正的迭代器模式 186 8.20 真正的工厂模式 187 8.21 真正的门面模式 187 8.22 真正的命令模式 188 8.23 真正的模板方法模式 188 8.24 真正的适配器模式 188 8.25 业务与逻辑分开 189 8.26 架构不是功能的要求,但却是工程的要求 189 8.27 你需不需要一个库 190 8.28 可复用与可移殖的区别 190 8.28 再谈可复用 193 8.29 真正的可复用 193 8.30 你能理解XP编程吗 194 8.31 构件与接口,软工 195 8.32 设计方法论 196 8.33 真正的interface 198 8.34 真正的对接口进行编程 200 8.35 实践方法之极限编程 200 8.36 设计模式复用与框架复用 201 第三部分 进阶: C,C++代码阅读与控制 201 第9章 语法与初级标准库 202 9.1 C++的基于过程设计 203 9.2 C++的基于对象设计: 模板与设计 203 9.3 面向对象设计 204 9.4 泛型开发与初级StdC库 204 第10章 数据逻辑与STL库 204 10.1 仿函数 204 10.2 iterater 204 10.3 adapter 205 第11章 高级代码逻辑与LOKI库 205 11.1 typelist 205 11.2 traits 206 11.2 policy 206 第四部分 一个例子:游戏引擎和实现 206 第12章 设计(需求分析) 207 12.1 第一天:接到一个案子 207 12.2 第二天:需求分析 208 第13章 设计(领域分析与抽象) 210 13.1 原语设计 210 13.2 了解Yake 216 13.3 GVWL1.0开发 222 13.4 范型设计与实作 223 第14章 编码 224 14.1 原语设计 224 14.2 实现《梦想与财富》 224 第15章 重构 225 15.1 增加Jxta 225 第五部分 225 选读 225 字符与字符串 226 为什么我说Java是脚本语言 226 宽松语法,无语法语言 227 Linux与3D 228 伪码语言 229 最强大的语言原来是预处理 230 语言宿主 231 shell编程和交互式语句编程 232 Debug,编译期断言 232 图形原理之位图,图象和字体 233 为Windows说些好话 233 Minlearn Ruby (5) 网络原理与P2P 234 Minlearn Ruby(4) 字符串与WEB 234 加密与解密 235 Minlearn(3)载体逻辑 236 Minlearn(2) 平台与并发 237 Minlearn(1)平台之持久 237 平台之多媒体编程 237 Minlearn Ruby 238 思想,维度,细节 240 理想 241 XML 242 面向更好复用的封装机制 243 SOA 244 浮点标准与实现 244 Desktop,web,internet,云计算不过WEB的集中化这种说法的偷换概念 246 编程设计与经济 246 晕计算 247 在形式主义与直觉主义之间:数学与后现代思想的根源 248 Scheme 程序语言介绍之一 248 与软工有关的哲学 辩证 251 富网页技术 251 形式维度 252 开源与开放 253 Core learning and min learing编程 253 与软工有关的哲学 联系 254 本地化和语言编码 254 学习与维度 255 跟软件有关的哲学.唯物主义 255 关于逻辑的逻辑 256 合理性 257 语言,道理和感情 258 可恶OO 259 互联网与企业开发 259 会学习的人首先要学历史 260 离散数学与代数系统 262 线代与矩阵 262 计算机与编程 263 真正的二进制 265 真正的文件 266 真正的数据 267 真正的Unicode 267 真正的Windows消息 269 真正的XML 270 真正的GUI 271 设备环境 271 真正的MFC 273 真正的虚拟机 275 真正的.NET 276 真正的脚本 278 真正的并发性 279 真正的反工程 280 真正的DSL 282 真正的多范型设计 284 真正的调试 285 真正的浮点数 286 真正的布尔 288 真正的整型数 289 真正的引用 290 真正的RTTI 290 真正的句柄 292 真正的循环 293 真正的STL 293 真正的容器 295 真正的智能指针 295 真正的数组索引 296 数据库 297 真正的可持久化 298 真正的类库 299 真正的COM 300 真正的DCOM 301 真正的Sun策略 302 真正的J2EE 303 真正的EJB 304 附录:一些领域逻辑,通用OO设计策略,框架设计 305 附录:参考文献 305 附录:一些建议 305
包含定义代码和测试代码,代码不复杂,有注释,池对象存取时间复杂度为常数级,多线程测试速度可达千万次/秒。 使用方法如下: 1.定义池,例如: FastPool<std::string> pool; 2.往池添加对象,例如: pool.Add("abc");//要注意这里传入的是构造对象的参数 3.取出一个对象以使用,例如: std::string* p = pool.Pop(); 这一步可以跟上一步结合起来: std::string* p = pool.AddAndPop("123");//这时候p就指向"123"这个刚加入池的std::string对象 4.存回对象以重用,例如: pool.Release(p); 5.还有的时候需要删除池中的对象,例如: pool.Delete(p);//只删除一个对象 pool.DeleteNotUsed();//删除池中未使用的对象 pool.DeleteAll();//删除池中所有对象 上面的示例只是模板参数为std::string 时的用法。还有一些函数未列出。希望代码能给大家带来启发。 重新检查了一次,发现模板代码中区分类和基本数据类型的代码用到了另外自定义的库。需要做如下修改: #include<type_traits> //先定义一个模板用以区分类和基本数据类型的行为 template<class TT, bool val>struct ChangeClass {typedef typename TT Type;}; template<class TT>struct ChangeClass<TT,false> {typedef typename std::vector<void*> Type;}; 然后代码中的 typedef typename LK::Templates::UseT<LK::Templates::IsClassOrUnion<T>::value, std::vector<void>, T>::type TP; if (LK::Templates::IsClassOrUnion<T>::value) 改为: typedef typename ChangeClass<T, std::is_class<T>::value>::Type TP;//防止非类调用析构函数导致的错误 if (std::is_class<T>::value) 最后,欢迎喜欢编程的伙伴来qq群244953928探讨O(∩_∩)O

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值