这些代码如何相互关联?

时间:2019-09-20 04:06:22

标签: c++ reference

我正在阅读有关通用引用的Scott Meyers的article,但我不太了解这一部分:

  

第三个引用折叠上下文是typedef的形成和使用。有了这个课程模板,

template<typename T>
class Widget {
     typedef T& LvalueRefType;
     ...
};
     

以及模板的这种用法,

Widget<int&> w;
     

实例化的类将包含此(无效)typedef:

typedef int& & LvalueRefType;
     

引用折叠将其简化为以下合法代码:

typedef int& LvalueRefType;

正在使用类型int,但是模板用于类型Widget。这些代码之间如何关联? TIA。

1 个答案:

答案 0 :(得分:0)

本文的这一部分假定您对模板有所了解。如果您不熟悉模板术语,那么在尝试理解“引用折叠上下文”之前最好先学习模板。也许短暂的失败就足够了。我会在解释事情上犯错。

template<typename T>
class Widget {
     typedef T& LvalueRefType;
     ...
};

这是class template。它是定义类的蓝图,而无需实际定义类。在使用此蓝图之前,必须指定一个可在该蓝图中使用的类型(在此示例中由T表示)。

Widget<int&> w;

这定义了一个变量(w),该变量的类是使用蓝图生成的。还记得蓝图需要指定类型吗?本示例将int&指定为该类型。为什么int& *耸肩* 这是Scott Meyers想要使用的类型。作者可以自行决定类似的事情。不用担心。

那么当您指定类型时会发生什么?复制蓝图,并在副本中进行替换。在这种情况下,T的每个实例都被int&替换,从而给出了特定的类定义。该类定义称为名为Widget<int&>的实例化类。您在任何地方都看不到此定义;这是编译器可以解决的问题。但是,如果您愿意对有效的C ++语法感到松懈,则以下内容将建议类定义:

class Widget<int&> {
     typedef int& & LvalueRefType;
     ...
};

typedef行中,模板中的Tint&取代。我还在其后添加了一个空格,以将其与跟号分隔(T&T &表示同一意思)。这将带我们转到文章的下一行代码:

typedef int& & LvalueRefType;

您熟悉吗?设置的全部目的是获得看起来很奇怪的代码,该代码似乎利用了对引用的引用(对int的引用)。现在,我们开始进行参考折叠。您不能引用参考,但是语言作者并不想自动使这种模板使用无效。因此,在语言规范的某处有一个子句说,在这种情况下,编译器应通过摆脱麻烦行中的“&”号来调整实例化的类。

从我们要处理的行中删除与号时,您将得到引用的最后一行代码。这实际上是编译器在生成Widget<int&>的定义时将使用的内容。

typedef int& LvalueRefType;

这是对模板的快速而又不完整的了解,它的细节足够使(希望)理解本文的这一部分。