我正在阅读一篇关于typename
#35的本周大师文章。最后,您可以找到以下代码片段:
#include <iostream> using std::cout; using std::endl; struct Rose {}; struct A { typedef Rose rose; }; template<class T> struct B : T { typedef typename T::rose foo; }; template<class T> void smell( T ) { cout << "awful" << endl; } void smell( Rose ) { cout << "sweet" << endl; } int main() { smell( A::rose() ); smell( B<A>::foo() ); }
我不明白这个。我的第一个猜测是,第二次smell
调用导致模板smell
由于您容易忽略的内容而被实例化(否则笑话应该是关于什么的?!但这两个电话都会导致"甜蜜"被打印出来。毕竟,这不是意料之中的吗?在typedef Rose rose;
中,Rose
不是依赖名称,所以这很好。在typedef typename T::rose foo;
中,rose
是依赖的,但typename
减轻了这一点。我的问题:
- 这个片段有什么意义?我在这里缺少幽默感吗?
- 这篇文章是 1998 年的;是否有任何语言更改改变了这段代码的作用?
这是 godbolt 上片段的精简版本。我测试了每个看起来很旧的编译器(例如gcc-4.4.1
,但请注意,上面的代码片段仍然比gcc-4.4.1
年大 11 年)。
你对代码的理解是正确的。这里的笑话参考了莎士比亚的《罗密欧与朱丽叶》中的台词:
名字里有什么?我们称之为玫瑰
的 用任何其他名字闻起来都是甜的;
这通常被解释为"任何其他名字的玫瑰闻起来都像甜的"。
或者在此代码的情况下:
A::Rose
,使用任何其他类型名称,仍然会使smell()
打印"sweet"
。