首页 > 解决方案 > Herb Sutter 在 GotW #35 中关于 typename 的代码玩笑过时了吗?

问题描述

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

#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被实例化,因为你很容易忽略某些事情(否则应该开什么玩笑?!)。但是这两个电话都会导致“甜蜜”被打印出来。毕竟,这难道不是意料之中的吗?In typedef Rose rose;,Rose不是从属名称,所以没关系。在typedef typename T::rose foo;,rose中是依赖的,但typename会减轻这种影响。我的问题:

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

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

标签: c++typename

解决方案


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

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

这通常被解释为“任何其他名字的玫瑰都会闻起来很甜”。

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

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


推荐阅读