掘金 后端 ( ) • 2024-04-16 13:44

在 C++ 中,模板是一种强大的工具,可以帮助我们编写通用的代码,提高代码的重用性和灵活性。模板在函数和/或类的结合下,存在诸多花样,其调用方法也各异,本文将以示例代码的形式抛砖引玉。

函数模板

函数模板是一种通用的函数定义,可以用来创建多个函数版本,以处理不同类型的参数

template <typenameT>
Tadd(Ta, Tb) {
    return a + b;
}


voidusing_function_template()
{
    // 调用 add<int>(1, 2),返回 3
    auto result1 = add<int>(1, 2);
    auto result11 = add(1,2);
    // 调用 add<double>(1.5, 2.5),返回 4.0
    double result2 = add(1.5, 2.5);
}

类模板

类模板允许我们定义通用的类,它可以处理多种不同类型的数据。类模板的语法形式如下:

template <typenameT>
classPair {
private:
    T first;
    T second;
public:
    Pair(Tf, Ts) : first(f), second(s) {}
};


voidusing_class_template()
{
    Pair<int> p1(1, 2);
    Pair p1(1, 2);//大于等于C++17, CTAD
    Pair<double> p2(1.5, 2.5);
}

之前的C++版本中,模板类,声明对象时要指定其类型;C++17后,拥有了CTAD(之前浅析CTAD中有提到过),可以由编译器自动推导。

普通类的模板成员函数

在普通类中,可以定义成员函数模板,这些成员函数模板可以接受不同类型的参数。

classMyClass {
public:
    // 成员函数模板
    template <typenameT>
    voidprint(Tvalue) {
        std::cout << "Value: " << value << std::endl;
    }
};


intusing_normal_class_function_template() {
    MyClass obj;
    obj.print<int>(5);
    obj.print(5.5);
    obj.print("Hello");


    return0;
}

普通类的模板函数调用,可以类比模板函数的调用,只是类的模板函数调用是基于对象的。

类模板的成员函数

类模板的成员函数可以是普通的成员函数,也可以是成员函数模板。例如,我们可以为上面的 Pair 类添加一个成员函数模板来比较两个键值对的大小:

template <typenameT>
classPair {
private:
    T first;
    T second;
public:
    Pair(Tf, Ts) : first(f), second(s) {}
    //普通成员函数
    TgetFirst() const { return first; }
    TgetSecond() const { return second; }


    //模板成员函数
    template<typenameU>
    boolIsFirstEqual(Uu)
    {
        return (u==first)?true:false;
    }
};


voidusing_calss_template_functions()
{
    Pair<int> p{3,4};
    //普通成员函数
    //直接调用即可
    p.getFirst();



    //模板成员函数
    //调用函数需要主动指定类型或有编译器推导
    p.IsFirstEqual<double>(3.0);
}

在上面的例子中,针对模板类分别定义了其普通成员函数和模板成员函数,使用模板类声明对象后,依次调用了其普通成员函数和模板成员函数。

总结

本文列举了模板函数和/或模板类的使用案例。以代码示例的形式说明了函数模板、类模板、普通成员函数、模板成员函数的使用方法。