初识C++模板

文章介绍了C++中的函数模板和类模板的概念及使用方法。函数模板允许编译器根据传入参数类型自动生成函数,类模板则用于创建可存储不同类型数据的类。模板提供了代码复用,但不保证类型安全,且不支持自动类型转换。类模板实例化产生具体的类,其成员函数也是模板函数。
摘要由CSDN通过智能技术生成

一、函数模板

template<typename T1, typename T2>
T1 Add(T1 x, T2 y)
{
    return x + y;
}

int main()
{
    cout << Add(1, 2) << endl;
    cout << Add(3.3, 4.4) << endl;
    cout << Add(5, 6.6) << endl;
    cout << Add(7.7, 8) << endl;

    return 0;
}

上述代码就是一个函数模板,template是定义模板的关键字,其后跟<>,里面使用class或者typename关键字来声明类型名,上述用typename声明了两个类型名,T1和T2;

其下紧跟一个函数,函数的参数、返回值以及函数内部都可以使用模板中声明的类型名。

在接下来调用函数的时候,编译器会根据传入参数的类型,根据模板自动生成一个模板函数,在上述的代码中,共生成了4个Add函数,其形参列表均不相同。

template<typename T1, typename T2>
T1 Add(T1 x, T2 y)
{
    return x + y;
}

int Add(int x, int y)
{
    return x + y;
}

int main()
{
    cout << Add(1, 2) << endl;
    return 0;
}

当显示实现了函数模板中的一个函数时,编译器就会先调用已有的函数,而不会根据模板自动生成。

除了编译器自动推演生成模板函数,还可以显示实例化出模板函数。

template<typename T1, typename T2>
T1 Add(T1 x, T2 y)
{
    return x + y;
}

int Add(int x, int y)
{
    return x + y;
}

int main()
{
    cout << Add<double, double>(1, 2) << endl;
    return 0;
}

如上述代码所示,在调用Add函数时,显示将类型实例化,编译器就会根据实例化的类型生成一个模板函数。

二、类模板

template<class T>
class Stack
{
private:
    T* _a;
    size_t _size;
    size_t _capacity;
public:
    Stack(size_t capacity = 4)
        :_capacity(capacity)
        , _size(0)
    {
        _a = new T[_capacity];
    }
    ~Stack()
    {
        delete[] _a;
        _a = nullptr;
        _size = _capacity = 0;
    }
    void Push(const T& x)
    {
        if (_capacity == _size)
        {
            T* _tmp = new T[_capacity * 2];
            for (size_t i = 0; i < _capacity; ++i)
            {
                _tmp[i] = _a[i];
            }
            _capacity *= 2;
            delete[] _a;
            _a = _tmp;
        }
        _a[_size++] = x;
    }
};

int main()
{
    Stack<int> st1;
    Stack<double> st2;

    st1.Push(1);
    st1.Push(2);
    st1.Push(3);
    st1.Push(4);
    st1.Push(5);

    st2.Push(1.1);
    st2.Push(2.2);
    st2.Push(3.3);
    st2.Push(4.4);
    st2.Push(5.5);

    return 0;
}

在上述的类模板中,定义了一个简单的Stack类模板,在使用类模板生成类的时候,一定要显示实例化具体类型。

使用了类模板后,可以让实例化出的Stack对象存储不同类型的数据。

三、特点

模板可以具有非参数类型,可以根据指定的大小动态创建结构;

模板类型无关的,具有很高的复用性;

模板运行时不检查数据类型,也不保证类型安全,只是替换类型;

模板自动推演不支持类型转换,如下:

template<class T>
T Sub(const T& x, const T& y)
{
    return x - y;
}

int main()
{
    // 错误的代码,自动推演的模板不支持隐式类型转换
    // cout << Sub(1, 2.2) << endl;
    cout << Sub<int>(1, 2.2) << endl;
    return 0;
}

因为Sub模板只有一个T的类型声明,第一个参数1是int类型,因此第二个参数也应该是int类型,如果是其他类型,则会报错;

因此,在参数类型不同时,需要显示指定参数类型;

类模板时一个模具,可以通过模板生成很多模板类,模板类是通过模板实例化出的具体的类。

类模板中的成员函数全部是模板函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王红花x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值