GotW #35 中关于 typename 的 Herb Sutter 代码笑话是否已过时?

Is Herb Sutter's code joke in GotW #35 on typename out of date?

我正在阅读 typename#35 上的一篇旧 Guru of Week 文章。在最后,您可以找到以下代码段:

#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 被实例化,这是由于您很容易忽略的事情(开什么玩笑,否则?!)。但是这两个调用都会导致 "sweet" 被打印出来。毕竟,这不是可以预料的吗?在 typedef Rose rose; 中,Rose 不是从属名称,所以没关系。在 typedef typename T::rose foo; 中,rose 是相关的,但 typename 减轻了这一点。我的问题:

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

Here 是 Godbolt 上的代码片段的浓缩版。我测试了每个看起来很旧的编译器(例如 gcc-4.4.1,但请注意,上面的代码片段仍然比 gcc-4.4.1 早 11 年)。

您对代码的理解是正确的。这里的笑话引用了莎士比亚的罗密欧与朱丽叶的台词:

What's in a name? That which we call a rose
By any other name would smell as sweet;

通常解释为 "A rose by any other name would smell as sweet."

或者在这段代码的情况下:

A::Rose, by any other type name, would still make smell() print "sweet".