网站空间费价格,江西个人网站备案,网址查询网站名称,海珠高端网站建设生鱼片和STL的关系#xff0c;你听过吗#xff1f;泛型编程和面向对象编程#xff0c;它们打架吗#xff1f;行为泛型和数据泛型#xff0c;各自的目的是#xff1f; 0 楔
俄罗斯生鱼片#xff0c;号称俄罗斯版的中国烤鸭#xff0c;闻名于世。其鱼肉#xff0c;源于… 生鱼片和STL的关系你听过吗泛型编程和面向对象编程它们打架吗行为泛型和数据泛型各自的目的是 0 楔
俄罗斯生鱼片号称俄罗斯版的中国烤鸭闻名于世。其鱼肉源于北极海域传统上用白鱼如omul、nelma 或 muksun 制作传统上与伏特加搭配加冰食用味道柔软、新鲜、冰爽。
虽然我隐约知道前苏联曾经有过一段人民生活物资贫溃的时期但我还是不太清楚26岁的Alexander Stepanov 是怎么吃生鱼片吃到严重中毒吃到住院吃到精神恍惚吃到在心中产生 STL 库的种子……
1 五段话
五段来自 STL之父 Alexander Stepanov / 亚历山大・斯特潘诺夫的话摘自其多个采访会谈内容。
谈专业—— “我出生在前苏联的莫斯科。我曾求学于莫斯科国立大学学习数学。但‘遗憾’的是我从来都没能成为数学家” 谈程序设计—— “程序设计就像同未理顺的复杂问题打的一场战斗要打好这场战斗数学首当其冲几个世纪以来数学的作用正在于此。如果将现在生动的数学体系作为实验证据对于解决人类遇到的复杂性问题数学还是最有效的” 谈中国—— “中国是一个伟大的国家。曾有过许多伟大的数学家秦九韶的《数书九章》就是古代数学中的经典……” 谈为什么没成为数学家—— “我实在不能对Tamagawa算术、Coxeter群等一些纯数学的东西感到兴趣” “我想用数学干点实事……” 谈数学专业对编程思想的影响—— “…… 1976年又要说回到苏联了我因为吃生鱼片得了严重的食物中毒而住院在精神恍惚中我忽然意识到并发的加法计算能力是基于加法是结合性的。同时我意识到并发的减法运算是和半群结构类型有关联的这就是最基本的重点算法是定义于代数结构基础之上的。我又花了一些年头意识到必须在正规公理上加入复杂性必要条件以扩展结构的概念接着又花了15年之久才完成全面的架构。我相信迭代器理论是计算科学的中心就象环或Banach区间理论是数学的中心一样。每次当我找到一个算法时我都要努力去寻求它所定义的结构基础。我想做的就是泛化地描述算法并乐此不疲。我可以花一个月时间去精确地描述一个众所周知的算法的泛化表示……” 2 课堂视频
我们对 STL对泛型编程的认识就从 STL 之父的介绍说起…… C感受16-Hello STL 泛型启蒙 3 泛型函数
3.1 语法
template typename T /* 类型参数列表 */
函数定义其中函数定义中可将 T 视为类型名字可用在函数返回值类型、函数参数、函数体内比如
template typename T
T add(T a, T b)
{return a b; // 相加结果的类型需为 T 或能隐式转换为 T
}类型参数列表和函数参数类似可以有多个参数
// 一个双类型参数的函数模板可用于输出带标题的值
tempate typename S, typename V
void OutputWithTitle( S const title, V const value)
{std::cout title : value;
}3.2 使用
调用者通常通过精准地指定参数类型为编译器提供准确的类型参数由编译器在代码需要处使用明确的类型替换模板中对应的类型参数比如上述示例中的 T、S 、V在编译器自动生成实际函数。由“函数模板”生成的函数需要时我们会称它为 “模板函数”。
例一、add 使用
// 调用1 生成 int add (int a, int b) ...
auto r1 add (1, 2); // auto 是 C11 的新语法此处编译器可推出其为 int // 调用2 生成 double add (double a, double b) ...
double r2 add (1.1, 2.0); // 此处的 2.0 不能写成 2// 调用3 生成 std::string add(std::string a, std::string b) ...
std::string r3 add(std::string(Hello ), // 明确的std::string 类型std::string(STL) // 同上); // 将返回 Hello STL上述代码将生成三个版本的 add 函数。 其中r2 例中如果 2.0 写成 2, 将造成编译器无法判定原模板中唯一的类型参数 T 的实际类型。r3 例中如果直接传递纯C风格字符串即字符串祼指针Hello 和 “STL”将造成编译失败因为祼的字符串指针不支持 “相加” 操作。
例二、OutputWithTitle 使用
OutputWithTitle(姓名, 丁小明); // S和V都是 char const* 类型std::string title 积分;
double value 2999.052;
OutputWithTitle(title, value); // S→std::stringV→double;3.3 auto: C20 的骚操作
到了 C20 新标准一些简单的函数模板定义可以使用 auto 来简化写法。
比如经典写法
template typename T
void foo(T v)
{// ...
}在 20 新标下可写作
void foo(auto v)
{// ...
}注意如果需要多个参数模板而每个参数模板都使用 auto 限定类型的话此时auto 并不执行 “同一类型” 的限定。比如
// a , b 都是 auto但并不存在类型必须一致的限定
auto add(auto a, auto b)
{return a b;
}// 以下调用成立
auto r add(900, 99.99); // 返回 999.99看起来很自由但如此 “挣脱类型的束缚”反倒容易滋生程序逻辑错误的恶果。
4. 泛型数据
有些时候——哪怕不是数学家——我们也会更加关心一个类型内部的组成结构而不太关心或者可以相对放心地忽略数据的内部组成的类型。
比如一个数学软件可能希望有个类型可以表示二维笛卡尔坐标Cartesian coordinates中的二维直角坐标点不关心其中的x, y 坐标采用哪种类型。 像“不关心”或 “随便”这样的用语记得要反过来理解它们的真实意思不是真的不在乎面是“干嘛分这分那我都要”。 template typename T
struct Point
{T x, y; // 用 T 表示 x, y 将来的真实类型二者一致
};和函数模板自动推理出函数略有不同实际使用中类的模板转换成类时通常需要在类class或struct之后带上 其中 T 用于明确指定所需模板参数的真实类型。
// 使用 int 实例化类模板
Pointint p1;
p1.x 10
// 可将 float 赋 .y只是转换过程中小数位会丢失
p1.y 9.8f; // 使用 float 实例
Pointfloat p2;
p2.x 99.f;
p2.y 100; // 同样此时不存在语法错误以上示例中之所以能跨类型赋值是因为此时无论 p1 还是 p2 内部的 x, y 的类型都已经明确指定了。
定义类模板时各类型参数既可用于指定成员数据的类型也可用在成员方法包括构造、析构等身上返回值、入参、函数内临时变量定义等等
template typename T
struct Point
{T x, y;Point() default; // 默认构造 C11语法Point(T x, T y): x(x), y(y) // 成员数据初始化列表{}// 让 x, y 各自增加指定的长度void IncBy (T dx, T dy){x dx;y dy;}
};构造、成员数据初始化列表知识点讲 见《Hello Object 封装版.下》 等课堂。 注意Point的第二个构造函数和 IncBy() 成员函数都用到了 T它就是定义类模板时的那个T无需在函数自身加 template typename 作定义。
继续本体不包含 当构造函数使用到所在类模板的类型参数并且构造对象时的入参能明确的完整地推后出类模板的所有模板参数则从 17 新标开始定义对象时不显示指定类模板的类型入参全部或部分也是可行的比如
Point p3 (99, 100); // 相当于 Pointint
Point p4 (99.0, 100.0); // 相当于 Pointdouble
Point p5 (std::string(90), std::string(12.345)); // 虽然奇怪但也合法我们当然举双手双脚反对 p5 的类型 Pointstd::string 试想对它调用 IncBy(“哦”, “哈”)之后……
5 初窥 vector
vector 翻译为 “矢量”它是 STL 中最经典的的一个数据容器类模板。请阅读以下示例代码在下一节课一上课我们就来完善它
#include vectorusing namespace std;struct 鸡精 { void 忍耐() { cout 欢迎品尝\n; } };
struct 象妖 { void 愤怒() { cout 大胆可笑\n; } };int main()
{ vector鸡精 v1; // 鸡精专用瓶vector象妖 v2; // 象妖专用瓶std::cout 妖怪我叫你一声你可敢答应?\n;...鸡精 sj1;v1.push_back(sj1);象妖 dx1;v2.push_back(dx1);...
}只是看可学不会编程哦像 STL 这样的库更是需要动手实践。谁出题有专业的一线编程多年的同行为你出题为你批改欢迎到本课原发站 www.d2school.com 做作业提问扎实扎实踏出编程学习的每一步看似“劳累”但这么做的你会获得更快的进步。