C++中的模板、STL和函数对象
C++的标准库类型
C++的标准库是一套由标准规定,并且大多数编译器都支持的类、函数、类型和对象。
标准库中定义的类型可以粗略地分为:
- 基本类型:int、char、bool、float、double等
- 复合类型:array、enum、struct、union、class、pointer、reference等
- STL容器:vector、list、deque、set、map等
- STL算法:标准库定义的一系列算法,如sort、find等
- 迭代器:用于遍历容器元素
- 函数对象(即function):特殊的类,其对象可以像函数一样被调用。
- 其他工具类和函数:包括智能指针(shared_ptr、unique_ptr等),日期和时间处理(chrono库), 字符串流(stringstream等)等。
模板
模板(Templates)是一种在编译时从一个公共蓝图产生多个实体的机制。这些实体可以是函数(称为函数模板),也可以是类(称为类模板)。通过模板,我们可以编写与类型无关的代码。例如,我们可以编写一个模板函数来交换两个对象的值,不论这两个对象的类型是什么。
示例:
template <typename T>
void swap(T& a, T& b)
{
T temp = a;
a = b;
b = temp;
}
在上面的例子中,swap就是一个函数模板,它可以接受任何类型的参数a和b。
STL
STL是使用模板构建的一组通用的数据结构和算法的集合。STL包含了各种容器(如vector、set、map等)、算法(如sort、find等)、迭代器以及函数对象等模板类和模板函数。
在C++中,模板的类型参数(包括STL容器和算法的类型)都是在编译时期确定的。
STL容器
STL(Standard Template Library)容器 是模板类的一种。例如,std::vector 是一个模板类,它可以存储任何类型的对象。你可以创建一个 std::vector 来存储整数,或者创建一个 std::vectorstd::string 来存储字符串。
STL算法
STL算法 则通常是模板函数,它们可以对各种数据类型进行操作。例如,std::sort 是一个模板函数,它可以对任何类型的元素进行排序,只要这些元素支持比较运算符。
函数对象function
编译时确定函数类型,运行时确定调用哪个可调用对象。
std::function 是一个模板类,它的类型参数在编译时确定。然而,它封装或者说存储的可调用对象是在运行时绑定的。这意味着可以在程序运行时决定 std::function 对象应调用哪个函数或者可调用对象。
例如:
std::function<void(int)> func;
if (some_condition) {
func = [](int x){ std::cout << "Function 1: " << x << '\n'; };
} else {
func = [](int x){ std::cout << "Function 2: " << x << '\n'; };
}
func(10); // 调用的函数取决于 some_condition 的值
在上面的例子中,std::function<void(int)> 类型在编译时就已经确定了,但是具体要调用哪个 lambda 函数则是在运行时由 some_condition 的值决定的。因此我们可以说,std::function 允许我们在运行时动态地决定调用哪个函数或者可调用对象。