2010-02-17 68 views
5

这是一个类模板的片断,这是造成编译错误:预计嵌套名称说明符之前“sktraits”

/* Secondary index class */ 
template<class TKey, class TVal, class key_traits, class val_traits> 
template<class TSecKey, class sktraits> 
class CBtreeDb<TKey, TVal, key_traits, val_traits>::CDbSecondaryIndex: protected CBtreeDb<TKey, TVal>, public IDeallocateKey 
{ 
public: 
typedef TSecKey   skey_type; 
typedef typename sktraits       skey_traits; 
typedef CNewDbt<TSecKey, sktraits>    CDbSKey; 
typedef typename iterator_t<TSecKey, skey_traits> iterator; 
typedef typename iter_lower_bound_t<skey_type> iter_lower_bound; 
typedef typename iter_upper_bound_t<skey_type> iter_upper_bound; 

CDbSecondaryIndex(CDbEnv* pEnv, u_int32_t flags, bool bAllowDuplicates=false): 
    CBtreeDb(pEnv, flags, bAllowDuplicates) 
{ 

} 

    // Class implementation continues ... 
}; 

的编译器错误消息我得到的是:

expected nested-name-specifier before 'sktraits'. 

其实,这个错误发生在每个typedef声明之后typename

我已经在过去使用VS2005和VS2008在X上成功编译了此代码P.

我目前正在建设在Ubuntu 9.10,使用gcc 4.4.1

我看着这个错误在谷歌和它看来,typename是没有必要的就行了(如果发生错误),这是因为标准假设是该位置的标识符是一种类型。 g ++似乎在抱怨,因为它预计任何typename声明都是合格的(即A :: B)。

这是对问题的正确诊断 - 如果是的话,那我该如何“完全符合”typename

总之,我该如何解决这个问题?

+0

我设法解决这个问题(即得到代码编译) - 只需删除typdef decl后面的'typename'即可。 虽然头文件现在编译成功,但我仍然不满意,因为我想知道为什么我必须删除typename(尤其是在STL类中使用类似符号时)的底层(即技术原因) – 2010-02-17 12:52:48

回答

0

以下是不允许的:

template<class A> 
template<class B> class F { ... }; 

您可以在一个类/函数定义之前最多一个​​template<>规范。

+0

请解释。科莫人不同意:http://www.comeaucomputing。com/techtalk/templates /#outsidedef - 我没有标准的方便,但Comeau是相当可靠的符合标准。 – 2011-12-01 04:21:49

+0

14.5.2/1中的标准说明:“定义在其类模板定义之外的类模板的成员模板应使用类模板的模板参数以及成员模板的模板参数指定“,并给出一个例子:'template template int string :: compare(const T2&s)'。 – 2011-12-01 05:57:12

7

typename是需要指定一个从属名称实际上是一种类型。你的名字不是依赖名字,所以不需要或允许typename

更新标准实际上有这样的语法定义:

类型名,SPECI网络ER
    类型名称 嵌套名称SPECI网络ER identi网络呃
    类型名称 nested-名称专用 模板 选择 简单模板id

其他两个地方,你可以使用typename关键字是模板参数列表和using声明(在后一种情况下,它也必须跟着一个嵌套名称说明符)。

相关问题