我正在阅读有关通用引用的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。
答案 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
行中,模板中的T
被int&
取代。我还在其后添加了一个空格,以将其与跟号分隔(T&
和T &
表示同一意思)。这将带我们转到文章的下一行代码:
typedef int& & LvalueRefType;
您熟悉吗?设置的全部目的是获得看起来很奇怪的代码,该代码似乎利用了对引用的引用(对int
的引用)。现在,我们开始进行参考折叠。您不能引用参考,但是语言作者并不想自动使这种模板使用无效。因此,在语言规范的某处有一个子句说,在这种情况下,编译器应通过摆脱麻烦行中的“&”号来调整实例化的类。
从我们要处理的行中删除与号时,您将得到引用的最后一行代码。这实际上是编译器在生成Widget<int&>
的定义时将使用的内容。
typedef int& LvalueRefType;
这是对模板的快速而又不完整的了解,它的细节足够使(希望)理解本文的这一部分。