简单类型说明符是模板参数

时间:2017-11-15 16:48:48

标签: c++ language-lawyer

根据ISO 14882:2011§14.6.2.1:

  

如果类型是 - 模板参数

,则类型是依赖的

根据§ISO14882:2011 14.6:

  

模板声明或定义中使用的名称,即   取决于模板参数,假定不命名类型,除非   适用的名称查找查找类型名称或名称是合格的   通过关键字typename。

但是

template <typename T> class U
{
    typename T t; // ill-formed, i have an compilier error
};

“依赖名称”和“模板声明或定义中使用的名称是否依赖于模板参数”是相同的概念? 我试图解决我的误解,因为它看起来像标准中的断言(ISO 14882:2011§14.6.2.1)和标准T t中的例子之间的冲突;

1 个答案:

答案 0 :(得分:1)

您的示例代码格式不正确,因为ISO第17.7.3节(http://eel.is/c++draft/temp.res#3):T不是nested name-specifier

因此,T除了用作模板参数的typename T之外别无他法。即编译器不能弄错,所以你不需要用typename-specifier来限定它。

需要typename-specifier的从属类型示例为T::value_type,因为value_type 的实际类型/值取决于 T 1}}是。在这种情况下,你必须帮助编译器:

template <typename T> class U {
  using t = T;                      // OK
  using u = T::value_type;          // ill-formed: needs typename-specifier
  using v = typename t::value_type; // OK: qualified with typename keyword
};

让我们说你有以下内容:

class foo {
  constexpr static int value_type = 7;
}

class bar {
  using value_type = int;
}

这就是上面的第二个typedef行格式不正确的原因:如果Tfoo,那么value_type实际上不是一个类型,而是一个名称非常混乱的常量。如果Tbar,那么一切都很顺利。但编译器无法知道这一点,所以你必须帮助他,并向他保证value_type实际上是一种类型。这也意味着如果您尝试编译U<foo>,将会遇到编译错误。

注意:我对typedef使用了C ++ 11语法,因为我觉得它更具可读性。如果您使用typedef代替using,则上述说明仍然有效。