当前位置: 首页 > news >正文

C++模板基础(九)

完美转发与 lambda 表达式模板

void f(int& input)
{std::cout << "void f(int& input)\t" << input << '\n';
}void f(int&& input)
{std::cout << "void f(int&& input)\t" << input << '\n';
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x = 3;f(x); //int&f(5); //int&&return a.exec();
}

在这里插入图片描述

void f(int& input)
{std::cout << "void f(int& input)\t" << input << "\n\n";
}void f(int&& input)
{std::cout << "void f(int&& input)\t" << input << "\n\n";
}template<typename T>
void fun(T input)
//void fun(T& input) //无法将int x = 3;从int转换为int&
//void fun(T&& input) //&&是万能引用,右值引用的变量是左值。输出同void fun(T input)
{std::cout << "template<typename T> void fun(T input)\n";f(input);
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x = 3;fun(x); //int&fun(5); //参数是int&&类型,但是调用了void f(int& input)return a.exec();
}

在这里插入图片描述

● (C++11) 完美转发: std::forward 函数
– 通常与万能引用结合使用
– 同时处理传入参数是左值或右值的情形

#include<utility>void f(int& input)
{std::cout << "void f(int& input)\t" << input << "\n\n";
}void f(int&& input)
{std::cout << "void f(int&& input)\t" << input << "\n\n";
}template<typename T>
void fun(T&& input)
{std::cout << "template<typename T> void fun(T input)\n";f(std::forward<T>(input)); //完美转发
}
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x = 3;fun(x); //int&,调用void f(int& input)fun(5); //int&&,调用void f(int&& input)return a.exec();
}

在这里插入图片描述

void f(int& input)
{std::cout << "void f(int& input)\t" << input << "\n\n";
}void f(int&& input)
{std::cout << "void f(int&& input)\t" << input << "\n\n";
}template<typename T>
void fun(T input)
{std::cout << "template<typename T> void fun(T input)\n";f(std::forward<T>(input)); //完美转发不能处理的情形
}
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x = 3;fun(x); //int&,调用void f(int&& input)fun(5); //int&&,调用void f(int&& input)return a.exec();
}

在这里插入图片描述

void f(int& input)
{std::cout << "void f(int& input)\t" << input << "\n\n";
}void f(int&& input)
{std::cout << "void f(int&& input)\t" << input << "\n\n";
}template<typename... T>
void fun(T... inputs)
{std::cout << "template<typename... T> void fun(T... inputs)\n";f(std::forward<T>(inputs)...); //包展开技术
}
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x = 3;fun(x); //int&,调用void f(int&& input)fun(5); //int&&,调用void f(int&& input)return a.exec();
}

在这里插入图片描述

void f(int& input)
{std::cout << "void f(int& input)\t" << input << "\n\n";
}void f(int&& input)
{std::cout << "void f(int&& input)\t" << input << "\n\n";
}template<typename... T>
void fun(T&&... inputs) //万能引用参数包
{std::cout << "template<typename... T> void fun(T... inputs)\n";f(std::forward<T>(inputs)...); //包展开技术
}
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int x = 3;fun(x); //int&,调用void f(int& input)fun(5); //int&&,调用void f(int&& input)return a.exec();
}

在这里插入图片描述
● (C++20) lambda表达式模板

消除歧义与变量模板

struct Str
{const static int internal = 3;
};int p = 5;template<typename T>
void fun()
{//internal是T中的一个具体数据,乘以变量pstd::cout << T::internal*p << '\n';
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);fun<Str>();return a.exec();
}

在这里插入图片描述
● 使用 typename 与 template 消除歧义
– 使用 typename 表示一个依赖名称是类型而非静态数据成员

struct Str
{using internal = int;
};template<typename T>
void fun()
{//internal是T中的一个数据类型,p是该类型的一个指针int x = 5;typename T::internal* p = &x; //加上typename表示internal是T中的一个数据类型,消除了歧义Str::internal* ptr = &x; //加上限定名Str消除歧义std::cout << p << '\n' << ptr << '\n';
}
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);fun<Str>();return a.exec();
}

在这里插入图片描述

– 使用 template 表示一个依赖名称是模板
– template 与成员函数模板调用

struct Str
{template<typename T>static void internal(){std::cout << "Str::template<typename T> static void internal()\n";}
};template<typename T>
void fun()
{//T::internal<int>(); //编译器可能认为<是小于运算符。Warning: Use 'template' keyword to treat 'internal' as a dependent template nameT::template internal<int>(); //OK,使用了template消除了歧义
}
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);fun<Str>();return a.exec();
}

在这里插入图片描述

struct Str
{template<typename T>void internal() //非static函数{std::cout << "Str::template<typename T> static void internal()\n";}
};template<typename T>
void fun()
{T obj;//obj.internal<int>(); //编译器可能认为<是小于运算符。Warning: Use 'template' keyword to treat 'internal' as a dependent template nameobj.template internal<int>();  //OK,使用了template消除了歧义
}
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);fun<Str>(); //输出同上return a.exec();
}

● (C++14) 变量模板
– template T pi = (T)3.1415926;

template<typename T>
T pi = (T)3.141592653;int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);std::cout << pi<double> << '\n';std::cout << pi<float> << '\n';std::cout << pi<int> << '\n';return a.exec();
}

在这里插入图片描述

template<typename T, unsigned v>
unsigned MySize = (sizeof(T) == v);int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);std::cout << MySize<float, 4> << '\n';std::cout << MySize<int, 2> << '\n';return a.exec();
}

– 其它形式的变量模板
std::is_same

参考
深蓝学院:C++基础与深度解析
cppreference

http://www.lryc.cn/news/59857.html

相关文章:

  • 【剑指 Offer】(1)
  • 每日一题 leetcode1026 2023-4-18
  • 【Python_Scrapy学习笔记(十二)】基于Scrapy框架实现POST请求爬虫
  • 《花雕学AI》02:人工智能挺麻利,十分钟就为我写了一篇长长的故事
  • 做程序员累了想要转行?我想给大家分享一下看法
  • 如果你想从事人工智能职业,学习Python吧
  • 百模大战,谁是下一个ChatGPT?
  • Revit中怎么绘制多面坡度的屋顶及生成墙
  • 【jvm系列-07】深入理解执行引擎,解释器、JIT即时编译器
  • 【GCU体验】基于PaddlePaddle + GCU跑通模型并测试GCU性能
  • 解析hash(散列)数据结构
  • 《2023金融科技·校园招聘白皮书》新鲜出炉|牛客独家
  • 文明的标志:书写系统、修建城市、使用金属器
  • 算法:将一个数组旋转k步
  • 使用大华惠智双目半球网络摄像机DH-IPC-HD4140X-E2获取人流量统计数据
  • DC插装式流量阀压力阀
  • NumPy 数组学习手册:6~7
  • 【笔试强训选择题】Day6.习题(错题)解析
  • 磁盘分区-LINUX
  • SpringAOP入门基础银行转账实例(进阶版)------------事务处理
  • 【python学习】基础篇-常用函数-format函数 格式化操作
  • 团团面试经验
  • 今天面了个京东拿 38K 出来的,让我见识到了基础的天花板
  • Qt创建SDK库(dll动态库)并调用SDK库(dll动态库)
  • 400以内的蓝牙耳机哪款好?400以内蓝牙耳机排行榜
  • 基于飞桨实现的特定领域知识图谱融合方案:ERNIE-Gram文本匹配算法
  • 前端基础复习
  • Vue2 API-源码解析
  • FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization
  • C/C++文档阅读笔记-A Simple Makefile Tutorial解析