添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
template class ClassName { // 对类模板进行次要偏特化,其中 T1 和 T2 均为指针类型 // 提供特定的实现

在上述示例中,我们对类模板 ClassName 进行了两种形式的偏特化。第一个偏特化对类型参数进行了主要偏特化,其中第二个类型参数被限定为 int。第二个偏特化对类型参数进行了次要偏特化,其中两个类型参数均为指针类型。

通过偏特化,我们可以根据特定的类型参数,为类模板提供更具体的实现。这使得类模板能够更好地适应不同的需求和类型组合。需要注意的是,偏特化只能应用于类模板,而不能应用于函数模板。

int main() {
    auto intZero = zero<int>;  // 隐式实例化为 int 类型的零值变量
    auto doubleZero = zero<double>;  // 隐式实例化为 double 类型的零值变量
    int explicitIntZero = zero<int>;  // 显式实例化为 int 类型的零值变量
    return 0;

在这个例子中,我们通过隐式实例化和显式实例化,分别生成了 int 类型和 double 类型的零值变量。

变量模板的使用注意事项:

public: templateSTL(T1 newKey,T2 newValue) : key(newKey),value(newValue){ qDebug()<<"templateSTL 模板类构造函数:"<<" key : "<<key<<" value : "<<value; // 自制操作运算符 比较两个数 bool operator < (const templateSTL<T1,T2>&T3) const; T1 key; T2 value; template<class T> class templateSTL2 public: templateSTL2(T newValue) : value(newValue) { qDebug()<<" templateSTL2 模板类构造函数:"<<" value : "<<value; // 自制操作运算符 比较两个数 bool operator = (const templateSTL2<T>&T_equal) const; T value; #endif // TEMPLATESTL_H

模板类源文件:

#include "templatestl.h"
template<class T1, class T2>
bool templateSTL<T1, T2>::operator <(const templateSTL<T1, T2> &T3) const
    return this->key < T3.key;
template<class T>
bool templateSTL2<T>::operator =(const templateSTL2<T> &T_equal) const
    return this->value == T_equal.value;
    void on_PB_template_clicked();
    void on_PB_templatecpp_clicked();
    void on_PB_clear_clicked();
    void on_PB_templateQt_clicked();
    void on_PB_templateclass_clicked();
private:
    // Qt 模板举例函数  模块需要和对应的函数的分号;匹配
    template<typename T>
    T setCreateTemplateFunction(const T &value);
    QString createTemplateFunction(QString key);
    // Qt 简单的模板函数
    //头文件声明一个函数模板
    template<class T>
    void swap(T & a,T & b);
    // C++ 模板举例函数
    template<typename T>
    T baseCppFunction(const T &value , int falg);
private:
    Ui::Dialog *ui;
    QVariant myVar;
    QMap <QString, QString> map;
#endif // DIALOG_H

主源文件:

#include "dialog.h"
#include "ui_dialog.h"
#include "QDebug"
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
    ui->setupUi(this);
Dialog::~Dialog()
    delete ui;
// 模板函数自定义实现
void Dialog::on_PB_template_clicked()
    // 传递整数
    setCreateTemplateFunction(1);
    setCreateTemplateFunction(-1);
    // 传递浮点数
    setCreateTemplateFunction(3.1415927);
    setCreateTemplateFunction(-3.1415927);
    // 传递字符
    QChar mychar = 'a';
    setCreateTemplateFunction(mychar);
    // 传递字符串
    QString str = "hello world";
    setCreateTemplateFunction(str);
    // 传递颜色
    QColor color(255,0,0);
    setCreateTemplateFunction(color);
    // 传递时间
    QDateTime dateTime = QDateTime::currentDateTimeUtc();
    setCreateTemplateFunction(dateTime);
    dateTime = QDateTime::currentDateTime();
    setCreateTemplateFunction(dateTime);
    // 传递字体
    QFont font;
    font.setItalic(true);
    font.setBold(true);
    font.setPointSize(20);
    setCreateTemplateFunction(font);
// 模板类型函数 关键:使用QVariant变量区分数据类型
template<typename T>
T Dialog::setCreateTemplateFunction(const T &value)
    myVar = value;
    qDebug()<<"value = "<<value<< " myVar = "<<myVar;
    // 使用switch可能效果更好哦
    // 恢复默认样式
    QTextCharFormat format;
    format.setForeground(Qt::black);
    ui->plainTextEdit_cout->setCurrentCharFormat(format);
    if (myVar.type() == QVariant::Type::Int) {
        ui->plainTextEdit_cout->appendPlainText("整数:" + myVar.toString());
        // 存储
        map.insert("Int",myVar.toString());
    else if (myVar.type() == QVariant::Type::Double) {
        ui->plainTextEdit_cout->appendPlainText("浮点数:" + myVar.toString());
        // 存储
        map.insert("Double",myVar.toString());
    else if (myVar.type() == QVariant::Type::Char) {
        ui->plainTextEdit_cout->appendPlainText("字符:" + myVar.toString());
        // 存储
        map.insert("Char",myVar.toString());
    else if (myVar.type() == QVariant::Type::String) {
        ui->plainTextEdit_cout->appendPlainText("字符串:" + myVar.toString());
        // 存储
        map.insert("String",myVar.toString());
    else if (myVar.type() == QVariant::Type::Color) {
        QTextCharFormat format;
        format.setForeground(QBrush(QColor(myVar.toString())));
        ui->plainTextEdit_cout->setCurrentCharFormat(format);
        ui->plainTextEdit_cout->appendPlainText("颜色:" + myVar.toString());
        // 存储
        map.insert("Color",myVar.toString());
    else if (myVar.type() == QVariant::Type::DateTime) {
        ui->plainTextEdit_cout->appendPlainText("当前时间:" + myVar.toString());
        // 存储
        map.insert("Double",myVar.toString());
    else if (myVar.type() == QVariant::Type::Font) {
        if (myVar.toString().split(',').size() > 1) // 防止下标越界 非法访问 导致程序崩溃
            ui->plainTextEdit_cout->setFont(QFont(myVar.toString().split(',').at(0),myVar.toString().split(',').at(1).toInt()));
        ui->plainTextEdit_cout->appendPlainText("字体:" + myVar.toString());
        // 存储
        map.insert("Font",myVar.toString());
    return value;
void Dialog::on_PB_templateQt_clicked()
    // 通过键获取值
    QString val;
    QMap<QString, QString>::const_iterator i = map.constBegin();
    while (i != map.constEnd()) {
        qDebug() << i.key() << ": " << i.value() << Qt::endl;
        val = createTemplateFunction(i.key());
        ui->plainTextEdit_cout->appendPlainText(val);
    // 模板函数交换两个数
    int num1 = 1;
    int num2 = 3;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num1 = "<<num1;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num2 = "<<num2;
    swap(num1,num2);//函数模板生成的模板函数
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num1 = "<<num1;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num2 = "<<num2;
    double num3 = 2.5;
    double num4 = 3.6;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num3 = "<<num3;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num4 = "<<num4;
    swap(num3,num4);
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num3 = "<<num3;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num4 = "<<num4;
    QChar num5 = 'a';
    QChar num6 = 'b';
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num5 = "<<num5;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num4 = "<<num6;
    swap(num5,num6);
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num5 = "<<num5;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num4 = "<<num6;
    QString num7 = "abc";
    QString num8 = "def";
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num7 = "<<num7;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换前 num8 = "<<num8;
    swap(num7,num8);
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num7 = "<<num7;
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" 交换后 num8 = "<<num8;
QString Dialog::createTemplateFunction(QString key)
    qDebug()<< " key = "<<key;
    return map.value(key);
// 采用引用传参可以直接修改变量的值
template<class T>
void Dialog::swap(T &a, T &b)
    T temp ;
    temp = a;
    a = b;
    b = temp;
// 基于C++模板函数实例
void Dialog::on_PB_templatecpp_clicked()
    // 第一组 is_same
    // 传递整数
    baseCppFunction(1,0);
    baseCppFunction(-1,0);
    // 传递浮点数
    baseCppFunction(3.14,0);
    baseCppFunction(-3.1415927,0);
    // 传递字符
    char c = 'a';
    baseCppFunction(c,0);
    // 传递字符串
    std::string str = "hello world";
    baseCppFunction(str.c_str(),0);
    // 第二组 is_convertible
    // 传递整数
    baseCppFunction(1,1);
    baseCppFunction(-1,1);
    // 传递浮点数
    baseCppFunction(3.14,1);
    baseCppFunction(-3.1415927,1);
    // 传递字符
    char cc = 'a';
    baseCppFunction(cc,1);
    // 传递字符串
    std::string strr = "hello world";
    baseCppFunction(strr.c_str(),1);
template<typename T>
T Dialog::baseCppFunction(const T &value, int falg)
    qDebug()<<"value = "<<value;
    QVariant myVar = value;
    // 会将整数和字符混淆 不够准确
#if 0
    if (std::is_integral<T>::value) {
        std::cout << "is_integral: " << value << std::endl;
        ui->plainTextEdit_cout->appendPlainText("is_integral: " + myVar.toString());
    if (std::is_floating_point<T>::value) {
        std::cout << "is_floating_point: " << value << std::endl;
        ui->plainTextEdit_cout->appendPlainText("is_floating_point: " + myVar.toString());
#endif
    if (falg == 0)
        //  使用same匹配类型是否相同
        if (std::is_same<T, int>::value) {
            std::cout << "整数: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_same int 整数: " + myVar.toString());
        else if (std::is_same<T, float>::value) { // 未匹配
            std::cout << "浮点数值: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_same float 浮点数值: " + myVar.toString());
        else if (std::is_same<T, double>::value) {
            std::cout << "double浮点数值: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_same double 浮点数值: " + myVar.toString());
        else if (std::is_same<T, char>::value) {
            std::cout << "字符: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_same char 字符: " + myVar.toString());
        else if (std::is_same<T, std::string>::value) { // 不太准确
            std::cout << "字符串: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_same string 字符串: " + myVar.toString() + "\n");
    else {
        if (std::is_convertible<T, int>::value) {   // 不太准确
            std::cout << "整数: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_convertible int 整数: " + myVar.toString());
        else if (std::is_convertible<T, float>::value) { // 不太准确
            std::cout << "浮点数值: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_convertible float 浮点数值: " + myVar.toString());
        else if (std::is_convertible<T, double>::value) { // 未匹配
            std::cout << "double浮点数值: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_convertible double 浮点数值: " + myVar.toString());
        else if (std::is_convertible<T, char>::value) {// 未匹配
            std::cout << "字符: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_convertible char 字符: " + myVar.toString());
        else if (std::is_convertible<T, std::string>::value) { // 匹配
            std::cout << "字符串2: " << value << std::endl;
            ui->plainTextEdit_cout->appendPlainText("is_convertible string 字符串: " + myVar.toString());
    return value;
void Dialog::on_PB_clear_clicked()
    ui->plainTextEdit_cout->clear();
// 模板类举例 【QString 类使用的是 Unicode 编码,因此在比较字符串时会考虑字符的 Unicode 值。比较的结果取决于所使用的排序规则和语言环境。】
void Dialog::on_PB_templateclass_clicked()
    // 创建模板类
    templateSTL<QString,int>T3("小明",23);
    templateSTL<QString,int>T4("菲菲公主",23);
    // 比较名字的长度
    if (T3.key < T4.key) {
        qDebug()<<T4.key + " size = "<<T4.key.size()<< " " + T3.key + " size = "<<T3.key.size();
    else {
        qDebug()<<T4.key + " size = "<<T4.key.size()<< " " + T3.key + " size = "<<T3.key.size();
    // 比较两个数是否相等
    templateSTL2<QString>T5("小明");
    templateSTL2<QString>T6("晓明");
    // 每个汉字的编码不同 类比16进制不相等
    if (T5.value == T6.value) {
        qDebug()<<"小明 = 晓明"<<"T5 size = "<<T5.value.length()<<"T6 size = "<<T6.value.length();
    else {
        qDebug()<<"小明 != 晓明"<<"T5 size = "<<T5.value.length()<<"T6 size = "<<T6.value.length();

ui设计文件:

作者:Qt历险记
原文:https://mp.weixin.qq.com/s/xDC4WXv_VqXlAnNjsLMVyw

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至[email protected] 举报,一经查实,本站将立刻删除。

(0)
  • 视频会议即服务(VCaaS):定义、工作原理和用例
  • 云呼叫遇上酒店业:Percipia 和 Webex by Cisco 合作
  • Webex 将 Peerless Network 纳入 Webex Calling 的云连接计划
  • 基于量子密钥的移动终端保密通信方案研究
  • 【远程医疗】7大场景方案缓解“看病难”的问题
  • IDC:2026年中国物联网市场规模近3000亿美元 全球占比约为25.7%
  • Vulkan 1.3.280 发布,附带 NVIDIA 光线追踪验证扩展
  • Zoom首席技术官黄学东为您解答有关 AI 的三大热点问题
  • Android 编译 FFmpeg 6.0 – 支持MediaCodec编解码
  •