赫伯·萨特在 GotW #35 中关于字体名的代码笑话过时了吗?



我正在阅读一篇关于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减轻了这一点。我的问题:

  1. 这个片段有什么意义?我在这里缺少幽默感吗?
  2. 这篇文章是 1998 年的;是否有任何语言更改改变了这段代码的作用?

这是 godbolt 上片段的精简版本。我测试了每个看起来很旧的编译器(例如gcc-4.4.1,但请注意,上面的代码片段仍然比gcc-4.4.1年大 11 年)。

你对代码的理解是正确的。这里的笑话参考了莎士比亚的《罗密欧与朱丽叶》中的台词:

名字里有什么?我们称之为玫瑰
的 用任何其他名字闻起来都是甜的;

这通常被解释为"任何其他名字的玫瑰闻起来都像甜的"。

或者在此代码的情况下:

A::Rose,使用任何其他类型名称,仍然会使smell()打印"sweet"

最新更新