c++ - 什么时候需要 "typename"关键字?

标签 c++ templates syntax typename

Possible Duplicate:
Officially, what is typename for?
Where and why do I have to put the template and typename keywords?

考虑下面的代码:

template<class K>
class C {
    struct P {};
    vector<P> vec;
    void f();
};

template<class K> void C<K>::f() {
    typename vector<P>::iterator p = vec.begin();
}

为什么在这个例子中需要“typename”关键字? 是否还有其他必须指定“typename”的情况?

最佳答案

简答:每当引用作为从属名称的嵌套名称时,即嵌套在具有未知参数的模板实例中。

长答案:C++ 中有三层实体:值、类型和模板。所有这些都可以有名称,仅名称并不能告诉您它是哪一层实体。相反,必须从上下文中推断出有关名称实体性质的信息。

当这种推断不可能时,你必须指定它:

template <typename> struct Magic; // defined somewhere else

template <typename T> struct A
{
  static const int value = Magic<T>::gnarl; // assumed "value"

  typedef typename Magic<T>::brugh my_type; // decreed "type"
  //      ^^^^^^^^

  void foo() {
    Magic<T>::template kwpq<T>(1, 'a', .5); // decreed "template"
    //        ^^^^^^^^
  }
};

这里是名称Magic<T>::gnarl , Magic<T>::brughMagic<T>::kwpq必须明确说明,因为无法判断:自从 Magic是一个模板,是 Magic<T> 类型的 性质取决于 T -- 例如,可能存在与主模板完全不同的特化。

是什么让 Magic<T>::gnarl从属名称是我们在模板定义中的事实,其中T是未知的。如果我们使用 Magic<int> ,这会有所不同,因为编译器知道(你保证!)Magic<int> 的完整定义.

(如果您想自己测试,这里有一个 Magic 的示例定义,您可以使用它。为简洁起见,请原谅在特化中使用 constexpr;如果您有旧的编译器,请随意更改静态成员常量声明为旧式 C++11 之前的形式。)

template <typename T> struct Magic
{
  static const T                    gnarl;
  typedef T &                       brugh;
  template <typename S> static void kwpq(int, char, double) { T x; }
};
template <> struct Magic<signed char>
{
  // note that `gnarl` is absent
  static constexpr long double brugh = 0.25;  // `brugh` is now a value
  template <typename S> static int kwpq(int a, int b) { return a + b; }
};

用法:

int main()
{
  A<int> a;
  a.foo();

  return Magic<signed char>::kwpq<float>(2, 3);  // no disambiguation here!
}

关于c++ - 什么时候需要 "typename"关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7923369/

相关文章:

python - 是我的人工编译器 : What is wrong with this Python 2. 5 代码吗?

r - 将算术运算符视为函数

c++ - 析构函数可以是最终的吗?

c++ - mem_fn 到成员对象的函数

C++ 代码未在 Visual Studio 中运行

c++ - 有没有办法使这个模板特化链接?

c# - C++/CLI 中 C# Array[] 的语法

c++ - 错误 c2953 : class template has already been defined

C++ 自定义分配器

c++ - 使用 typedef 的模板特化