1.基于Meyers“有效和现代的c ++”-模板类型推断

下午好,亲爱的读者!


本文是我阅读Scott Meyers的《 Effective and Modern c ++》一书时所写的一系列抽象文章中的第一篇。 在github.com专门建立的项目中,每一篇文章都将有一个单独的目录, 带有使用所描述功能和技术的示例。


模板类型推断


成功的设计是当消费者不知道设备如何工作,但一切都适合他时。


例如,模板类型的结论是存在模板函数时调用的,而没有任何模板和尖括号。 同时,编译器猜测在函数的特定对象中将需要使用哪种类型。


Meyers将显示的类型“ T”和由程序员在参数定义中指定的类型“ ParamType”进行划分。


1.参数视图-链接或指针


为了快速了解派生规则,我将以模板的形式反映出来:


输入类型 -> 类型,参数 -> 输出类型 [, 参数的最终类型 ]


带有链接的示例:


template<typename T> //   T void func(T& param) //   - T& int x = 0; //   int func(x); 

派生类型T时 ,参照性(*,&)被丢弃,因为在定义函数时已经指出了参照性(*,&),就好像它意味着“您在此处传递任何内容,我们将假定这不是链接,因为参照性已经在使用位置添加了-在我们的函数f“


按照相同的原理,如果在功能参数中指定了恒定性,则将其丢弃。 在链接,指针,不变性上,都施加了专有掩码。


提款计划


 //   int —> (T & param) —> int; const int —> (T & param) —> const int; const int & —> (T & param) —> const int //   int —> (const T & param) —> int; const int —> (const T & param) —> int; const int & —> (const T & param) —> int; //   int * —> (T * param) —> int; const int —> (T * param) —> const int; const int * —> (T * param) —> const int; //   int * —> (const T * param) —> int; const int —> (const T * param) —> int; const int * —> (const T * param) —> int; 

2.论点类型-通用参考


斯科特提到,稍后将考虑通用链接,因此只需很少考虑就可以记住他在此处分为rvalue和lvalue的参数规则。


 template<typename T> void func(const T&& param) 

左值的推理规则


斯科特声称,这是将T作为参考输出的唯一情况。
在以下示例中,函数描述中的参数类型为通用左值引用 。 可以看出,T是显示为链接还是恒定链接,具体取决于
从输入参数来看,在这种情况下,param参数本身的类型也是一个引用。


 lvalue int —> (T &&param) —> int &, param - int& lvalue const int —> (T &&param) —> const int &, param - const int& lvalue const int & —> (T &&param) —> const int &, param - const int& 

参数本身的类型也将被替换。 我认为这是由于该语言无法考虑左值变量分配的事实,该左值变量位于可以进一步移动的值之上。 稍后我们将找到通用链接,我们将对其进行解决。
为了验证T是否确实是类型引用,我在模板函数的主体中编写了T myVar ,该T同时显示并预期收到一条消息- “声明为引用但未初始化” -链接:)


右值的推理规则


第1款的“正常”规则适用。


 rvalue int —> (T &&param) —> int, param - int&& 

已经很明显,仅对于右值临时对象才“包括”通用引用,在其他情况下,当参数不是通用引用时,不会区分右值,左值


3.按值传递(原样)


当通过值传递时,原始参数的恒定性和引用性由于不必要的原因而被丢弃,因为它们是全新的独立对象,为什么它们需要与它们无关的限定符?


 int —> (T param) —> int const int —> (T param) —> int const int & —> (T param) —> int //       ,     const char * const —> (T param) —> const char * 

我想其他疯狂和不合逻辑的组合都会导致编译错误,事实证明,编译器的工作几乎总是可以理解的,您只需要听一遍这些解释即可。

Source: https://habr.com/ru/post/zh-CN414233/


All Articles