CPP-Templates

本文介绍了C++中的模板类和模板函数的基本概念与使用方法。通过具体示例展示了如何定义和实例化模板类,以及如何利用模板减少代码重复,提高代码复用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果我们要处理一批数据,则可以构造一个vector container. 假设数据是整数。随后我们需要类似的操作,但操作数是double。我们就要重新实现前面的container. 另外例子包括构造一个比较大小的函数,如果函数是整数,双精度,或者字符,我们需要分别实现。这显然是重复。

为了解决此类问题,c++推出了摸版类。类似概念还有函数摸版。
见下例子:

#include <iostream>
using namespace std;

template <class datatype>
class Compare{
public:
    Compare(datatype a, datatype b)
    {x=a;y=b;}
    datatype max()
    {return (x>y)?x:y;};
    datatype min()
    {return (x<y)?x:y;}
private:
    datatype x,y;
};
#include "template1.h"
int main( )
{
   Compare<int > cmp1(12,41);  //compare integer
   Compare<double > cmp2(90.213,23.076);  //compare double
   Compare<char> cmp3('n','x');  // compare char
   return 0;
}

template 定义了摸版。格式:

1 template<class 模板参数表>
2 
3 class 类名{
4 
5 // 类定义......
6 
7 };

其中,template 是声明类模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个,可以是类型参数 ,也可以是非类型参数。类型参数由关键字class或typename及其后面的标识符构成。非类型参数由一个普通参数构成,代表模板定义中的一个常量。

template<class type,int width>
2 
3 //type为类型参数,width为非类型参数
4 
5 class Graphics;

再看类定义:

template <class T>
class Matrix{
public:
...
private:
T *a;
int r,c;
};

template 暗示class Matrix是一个摸版,不是一个普通类。摸版参数在〈〉中暗示。此例子中,仅有一个摸版参数,名字是T. 但允许有多个。<>中的class暗示T是一个类型参数,意思是T被分配了一个类型,可以是任何类型,注意此处尽管用了class,但其实T也可以是普通类型,例如char, int等。在T被这样定义以后,它就可以在类的中间像普通类型名一样用来设置变量类型。

注意由于类是用摸版定义,因此类中的成员函数也需要改用摸版来定义。

上例中类摸版只有一个摸版参数。但其实一个类摸版或者函数摸版都可以有任意数目的摸版参数。摸版参数分为两类:类型参数(type parameters)和值参数(value parameters)。类型参数用关键字class或tupename*定义。 关键字typename是c++中后引入的,老版本编译器不支持,因此class是最常用的。值参数看起来象普通函数参数,但不能是浮点类型。(type parameters are preceded by the word class or typename* and designate arbitary types, Value parameters look like ordinary function parameters but may not be of floating point type).

例如我们可以定义一个stack摸版类,含两个参数,一个指定stack中单个元素的类型,另一个指定stack的尺寸。

template<class T, int size>
class Stack{
public:
Stack():n(0){};
bool empty(){return n<=0;}
void push(const T& e){s[n++]=e;}
void pop(){n--;}
T top(){return s[n-1];}
private:
T s[size];
int n;
};

当我们实例化这个类摸版时候,我们要给两个摸版参数分别赋值。例如我们可以声明一个整数stack,尺寸200。

Stack<int,200> x; //a stack with maximum of 200 int

像普通函数,摸版参数也能有默认值。例如:

template<class T=double, int size=100>

如果一个摸版参数有默认值,那么所有后续的都要有默认值。当有默认值时,我们定义时不用指定所有参数,例如:

Stack<Person> y //a stack with a maximum of 100 persons (person is class)
Stack<> z; //a stack with a maximum of 100 double.

最后,类并不是唯一可以被一般化的东西,函数也可以。看下面函数摸版例子:

int min(int a, int b)
{ 
    if(a < b)
    return a;
    else 
    return bl;
}

上述函数实现两个整数比较,推广到一般情况:

template<class T>
const T & min(const T& a, const T& b)
{
if(a<b)
return a;
else
return b;
}

第一行首先暗示是个摸版,T是类型参数名字。接下来一行给出了函数定义。int 被T 代替。注意a,b被写成了常引用,因此避免了拷贝整个对象。

另外一个例子,找数组中最小元素:

template <class T>
T & min_element(T f[], int n)
{
int m=0;
for(int i=1;i<n;i++)
if(f[i] < f[m])
m = i;
return f[m];
}
### Auto-Templates Implementation and Usage Auto-templates refer to mechanisms within programming languages or frameworks that allow for dynamic generation of templates based on certain rules, configurations, or data structures. These can significantly enhance productivity by reducing repetitive coding tasks while maintaining consistency across applications. #### Dynamic Template Generation in Programming Languages In modern programming environments, auto-template systems often leverage reflection or compile-time metaprogramming features to generate code automatically. For instance, C++ template metaprogramming enables the creation of generic functions and classes without sacrificing type safety during compilation[^1]. For configuration management tools like Ansible, Jinja2 templating engine facilitates automatic substitution of variables into predefined text files through placeholders similar to what was mentioned regarding logging practices[^2]. Here’s an example using Python's built-in string formatting capabilities: ```python template_string = "Hello {name}, welcome back!" formatted_message = template_string.format(name="Alice") print(formatted_message) ``` This snippet demonstrates how easily one could implement simple yet powerful auto-template functionalities directly inside scripts or larger software projects. When implementing singletons—a common design pattern—careful consideration must be given to thread safety and initialization order issues as noted previously about potential pitfalls when applying structural patterns such as adapters[^3]: ```cpp class Singleton { public: static Singleton& GetInstance() { static Singleton instance; return instance; } private: Singleton() {} }; ``` The provided C++ code shows a basic implementation where `GetInstance` ensures only one object exists throughout execution lifetime. --related questions-- 1. How does template specialization work in C++, and why might it benefit from being used alongside auto-templates? 2. What are some best practices for ensuring thread-safe operations within singleton implementations? 3. Can you provide examples of other structural design patterns besides adapter which may interact interestingly with auto-template concepts? 4. In what scenarios would employing conditional outputs over direct variable insertion prove more advantageous in log messages?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值