{
// 对类模板进行次要偏特化,其中 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编解码