根据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中的例子之间的冲突;
答案 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行格式不正确的原因:如果T
是foo
,那么value_type
实际上不是一个类型,而是一个名称非常混乱的常量。如果T
为bar
,那么一切都很顺利。但编译器无法知道这一点,所以你必须帮助他,并向他保证value_type
实际上是一种类型。这也意味着如果您尝试编译U<foo>
,将会遇到编译错误。
注意:我对typedef使用了C ++ 11语法,因为我觉得它更具可读性。如果您使用typedef
代替using
,则上述说明仍然有效。