模板网站是啥意思,做网站推广话术,明年做那个网站能致富,嵌入式软件开发工程师做什么文章目录 一、前言二、函数模板#xff08;Function Template#xff09;三、类模板#xff08;Class Template#xff09;四、变参模板#xff08;Variadic Template#xff09;五、模板的递归与元编程六、模板的局限与陷阱七、常用模板的实例八、C20 的概念#xff08… 文章目录 一、前言二、函数模板Function Template三、类模板Class Template四、变参模板Variadic Template五、模板的递归与元编程六、模板的局限与陷阱七、常用模板的实例八、C20 的概念Concepts九、总结 一、前言 C的模板Template是C中一种强大的特性它允许编写泛型程序即编写不依赖于具体类型的代码。模板提供了一种机制可以在编译时生成针对不同数据类型的代码而不需要重复编写相同逻辑的代码。这种机制使得代码更加灵活和可重用。 二、函数模板Function Template 函数模板允许我们编写与具体类型无关的函数从而使得函数能够处理不同的数据类型。函数模板的语法格式如下 templatetypename T1, typename T2,......,typename Tn
返回值类型 函数名(参数列表)
{// 函数体
}
注意typename是用来定义模板参数关键字也可以使用class(切记不能使用struct代替class)template typename T
T max(T a, T b) {return (a b) ? a : b;
}int main() {int x 10, y 20;double a 5.5, b 2.3;std::cout max(x, y) std::endl; // 输出 20std::cout max(a, b) std::endl; // 输出 5.5return 0;
} 在这里typename T 表示模板参数T它是一个占位符表示函数中可以使用任意类型。当我们调用这个函数时编译器会根据传递的参数类型自动推导出T的具体类型。 模板类型参数与非类型模板参数 除了类型参数外C还支持非类型模板参数。非类型模板参数通常是一个整数或指针值可以在编译时确定。例如 template typename T, int size
T arraySum(T (arr)[size]) {T sum 0;for (int i 0; i size; i) {sum arr[i];}return sum;
} 在这个例子中size 是一个非类型模板参数表示数组的大小。 显式指定模板参数 虽然编译器通常可以推导出模板参数但也可以显式地指定它们 int a maxint(3, 7);
三、类模板Class Template 类模板允许定义一个通用的类然后可以用不同的数据类型来实例化该类。典型的例子是标准库中的 std::vector 类它是一个类模板可以用来存储任意类型的元素。它的语法格式跟类模板类型下面是一个简单的类模板示例 template typename T
class Pair {
public:Pair(T first, T second) : first_(first), second_(second) {}T getFirst() const { return first_; }T getSecond() const { return second_; }private:T first_, second_;
};int main() {Pairint intPair(1, 2);Pairstd::string stringPair(hello, world);std::cout intPair.getFirst() , intPair.getSecond() std::endl; // 输出 1, 2std::cout stringPair.getFirst() , stringPair.getSecond() std::endl; // 输出 hello, worldreturn 0;
}
模板特化Template Specialization 模板特化允许我们为特定类型提供模板的特殊实现。模板特化有两种形式全特化和部分特化。全特化是为模板的特定类型提供完全不同的实现下面这个例子实例化Pair bool 时就会调用特化实现而不是通用实现 template typename T
class Pair {
public:Pair(T first, T second) : first_(first), second_(second) {}T getFirst() const { return first_; }T getSecond() const { return second_; }private:T first_, second_;
};template
class Pairbool {
public:Pair(bool first, bool second) : bits((first ? 1 : 0) | (second ? 2 : 0)) {}bool getFirst() const { return bits 1; }bool getSecond() const { return bits 2; }private:int bits;
}; 部分特化只适用于类模板而不是函数模板它允许为一部分模板参数提供特定实现 template typename T, typename U
class Pair {
public:Pair(T first, U second) : first_(first), second_(second) {}void print() { std::cout first_ , second_ std::endl; }
private:T first_;U second_;
};// 部分特化版本针对相同类型的 Pair
template typename T
class PairT, T {
public:Pair(T first, T second) : first_(first), second_(second) {}void print() { std::cout Matching types: first_ , second_ std::endl; }
private:T first_;T second_;
}; 在这个例子中当 Pair 的两个模板参数类型相同时编译器会选择部分特化版本而不是通用版本。 四、变参模板Variadic Template C11 引入了变参模板允许模板接受可变数量的模板参数。这对处理不定数量的参数或类型非常有用。 templatetypename... Args
void print(Args... args) {(std::cout ... args) std::endl;
} 在这个例子中print函数可以接受任意数量的参数并将它们打印出来。 五、模板的递归与元编程 模板递归和元编程是一种高级用法允许在编译时进行复杂的计算和逻辑处理。典型的例子是计算编译时的斐波那契数列 templateint N
struct Fibonacci {static const int value FibonacciN-1::value FibonacciN-2::value;
};template
struct Fibonacci1 {static const int value 1;
};template
struct Fibonacci0 {static const int value 0;
}; 这种编译期计算被称为模板元编程Template Metaprogramming用于在编译期执行逻辑判断和计算。 六、模板的局限与陷阱 编译时间: 模板实例化会增加编译时间尤其是对于大型代码库。 代码膨胀: 模板实例化会导致二进制文件膨胀因为每种类型的实例化都会生成独立的代码。 错误信息复杂: 当模板代码出错时编译器产生的错误信息通常较为复杂且难以理解。 七、常用模板的实例 STL 是 C 标准库的一部分其中包含了大量的模板如 std::vector, std::map, std::set 等。这些模板类使得开发者能够方便地使用各种数据结构和算法而不必为每种类型单独实现。 八、C20 的概念Concepts C20 引入了概念Concepts使得模板的类型约束更加明确。概念是一种用于限制模板参数的特性可以显著提高模板代码的可读性和可维护性。 template typename T
concept Addable requires(T a, T b) {{ a b } - std::convertible_toT;
};template Addable T
T add(T a, T b) {return a b;
} 通过引入概念编译器可以更早地检测出不满足条件的模板参数从而减少复杂的编译错误信息。 九、总结 C模板是一种功能强大且灵活的机制能够极大地提高代码的复用性和类型安全性。模板的学习曲线较为陡峭但一旦掌握它将成为编写高效、通用代码的利器。C20 的概念进一步增强了模板的表达能力使得模板编程更加直观和强大。