前言
"打牢基础,万事不愁" .C++的基础语法的学习."学以致用,边学边用",编程是实践性很强的技术,在运用中理解,总结.
引入
接上一篇C++基础语法:STL之函数对象(二)_预定义的函数符-CSDN博客.以<C++ Prime Plus> 6th Edition(以下称"本书")内容理解
一点想法
学习编程语言的边界
在对编程语言有一些理解,对代码有一定驾驭能力后,程序员会对自定义工具有一些想法.例如C语言是没有模板,没有函数对象这些概念的,但是C++有,他们也是根据需要开发出来的工具. 模拟一下开发工具的过程:1>想做什么.2>如何表达.3>如何实现.做到以后才可以用上工具.前两点属于概念上的设计,如何能实现呢?需要进入到语言的底层---编译器那个层面,用到编译器的api,在程序员没有得到编译器接口,不知道编译器编码规则的情况下是不能实现的.当然探索和进取的想法是很好的,但是要注意边界.
笔者在上一篇帖子中尝试了transform这个函数的还原,明显很窘迫,因为有的东西没办法在编程语言的层面去表达,而且费了半天劲还不一定有结果.对程序员来讲,工具开发等于现有工具的组合,属于应用层面的开发.编译器层面的工具开发,例如从现在C++20升级到C++24,那里面产生了新的概念和写法,才算得上是底层的升级.
编程语言会过时吗?
黑皮书<C++设计思想>出来都有20年了,回头再看,核心部分模板,容器这些概念也没变过,今天能理解其中的要义也是编程高手.编程语言会继续发展,产生更多更好的用法,基础部分不会变.再做一个假设,如果C语言被取代了,请问取代C的语言,有没有指针,链表这些概念在?所以考虑这个是多余的.
函数符回顾
函数符包括了函数指针和函数对象,用于处理容器元素.函数指针可用于类型确定的容器,函数对象用于容器类元素.函数对象的使用是先生成模板类对象,再调用重载的()运算符. 按照()内元素个数对函数对象分类.()内无元素称为生成器;有一个元素称为一元函数,有二个元素称为二元函数.
STL提供了预定义函数符,但没有明确指出是几元函数.猜测本书表16.12除了逻辑反和负号运算符是一元函数,其他都是二元函数.
自适应函数符
本书内容16.5.3,前三段话做了解,还是那个原因:没有源码.光是猜源码比较费劲.
因为书上所有二元函数,都没传参数进去,令人困惑.所以二元函数符的定义
template<class T>
TwoMeta{
T t1;
T t2;
public:
构造函数略;
T operator()(){return t1+t2};
}
书上原话:来看binder1st。假设有一个自适应二元函数对象f2( ),则可以创建 一个binder1st对象,该对象与一个将被用作f2( )的第一个参数的特定值 (val)相关联:
----解读:又一个令人不解的地方来了.可能是书上写错了
binder1st(f2,val) f1; //表达式看不懂,是函数调用?是构造函数?
binder1st f1(f2,val); //生成一个类型为binder1st,名称为f1的对象
后面的内容也挺令人费解,暂时理不出什么头绪,留待更新.
要使用的话,把这个函数背下来就可以了.
transform(gr8.begin(),gr8.end(),out,bind1st(multiplies<double>(),2.5));
更新
对函数对象做个较为全面的总结:
函数对象的概念:用于处理容器数据的函数指针.
为了处理容器数据,首先他创建了一个模板类(处理泛型),传入了参数(由函数的其他形参传入),
然后重载了operator()这个函数,使得调用起来和函数的调用差不多.
根据 operator()括号内的形参个数分为生成器,一元函数,二元函数,谓词,二元谓词等形式,给函数对象做了分类.
最大的问题是有没有提供函数符编写的接口,让程序员有发挥空间.如果没有,使用书上给出的函数符或者谓词等编写函数