【发布时间】:2010-11-21 01:04:06
【问题描述】:
编写一个模板函数,我声明:
template <typename T>
T invertible(T const& container, T::size_type startIndex, T::size_type endIndex);
使用 g++ 4.0.1 编译时出现错误:
error: 'T::size_type' is not a type
【问题讨论】:
编写一个模板函数,我声明:
template <typename T>
T invertible(T const& container, T::size_type startIndex, T::size_type endIndex);
使用 g++ 4.0.1 编译时出现错误:
error: 'T::size_type' is not a type
【问题讨论】:
你需要添加类型名。
即
template <typename T>
T invertible(T const& container, typename T::size_type startIndex, typename T::size_type endIndex);
在没有关于类型 T 的任何信息的情况下,编译器需要知道 T::size_type 指定了一个类型。
来自标准,第 14.6.2 节:
在模板声明或定义中使用并且依赖于模板参数的名称被假定为不命名类型,除非适用的名称查找找到类型名称或该名称由关键字
typename限定。
【讨论】:
原来我需要指定 T::size_type 是一个类型名。这是为什么呢?
template <typename T>
T invertible(T const& container, typename T::size_type startIndex, typename T::size_type endIndex);
【讨论】:
因为在解析模板声明时,T 是未知的。所以编译器根本不知道 T::size_type 是否存在。例如,它可能指的是静态变量。当您稍后使用模板时,T 当然是已知的,但错误发生得更早。请使用比 gcc 4.0.1 更古老的东西 ;-)
编辑:如果你用 -fpermissive 编译它,编译器可能会咀嚼你的代码,但他会给出警告。
【讨论】:
你发现 T::size_type 需要以 typename 为前缀。 为什么?
来自"C++ Templates: The Complete Guide"
语言定义解决了这个问题,通过指定通常依赖限定名称不表示类型,除非该名称以关键字typename为前缀。
...名称的类型名称前缀是必需的,当名称时
- 出现在模板中
- 合格
- 不用作基类规范列表或用于引入构造函数定义的成员初始化列表中
- 依赖于模板参数
此外,类型名前缀是不允许的,除非至少前三个条件成立。
【讨论】: