(1 探讨一)第一个尝试弄清的问题是父类模板与子类模板的模板参数的对应关系,如下图:
我们要弄清的问题是创建 function 对象时,传递的模板参数 _Fty , 传递到其父类 _Func_class 中时 ,父类的模板参数 _Ret 与 _Types 是什么样。这很关键。但模板实例化是发生在编译期间。编译器知道根据其自己定义的语法规则来确定这三个模板参数。所以即使是反汇编调试,也无法跟踪这个确定模板参数的过程。因此只能在模板的成员函数中增加一些打印语句,修改下库代码,如下图:
咱们猜测 , 当 function 的模板参数 _Fty = double ( char , int) 时,其父类模板的模板参数为 _Ret = double , _Types = { char , int }。
即 _Ret 见名知意时函数返回值的类型, _Types 是函数的参数类型。确实是这样的,在验证后。发生这么神奇的一幕,就在于那个承上启下的 宏定义 _Get_function_impl ,其有一个模板参数展开的动作。接着给出测试代码,首先是修改 reset 函数:
编写例子测试一下:
(2 探讨二) 再一个探讨的结论是:虽然创建的 function 对象绑定到某个函数类型。但实际为 function 对象赋值时候,可以采用兼容的函数类型,都可以的。只要实际待执行的函数类型的参数和返回值类型都兼容 function 模板参数的类型。测试如下:
因为数据的隐式类型转换是可以的,存在的。但不合理的类型转换,比如从 int 到 char 的转换,将导致代码行 13 报错,测试如下:
(3 探讨三) 函数的返回值可以从任意类型转换为 void 的类型,符合这个方向的函数,也可以绑定到 function 对象上,测试如下:
但反之则不成立。返回值为 void 的类型,不能转换为别的函数返回值类型。其实任意的函数返回值都不要求的话,就乱套了。测试如下
(4)