这是一些严格模板化的容器类的代码片段,用于绑定任意类型的任意数量的字段。我的一位同事发现我的代码没有在GCC下编译,经过大量研究后,他发现修复程序可以通过添加::template
来正确推断模板...我们之前都没见过这个并且我还不知道除了GCC需要的Visual Studio 2010不需要的代码之外还有什么。
template< typename T, int N >
struct SingleBindMemberStruct
{
typedef typename TGenericBindingHandler<T>::BindToUse BindType;
BindType m_Member;
template< typename ContainerClass >
static void AddBinding(CPackedTableDataSpec* spec)
{
// Perhaps with newer versions of the compilers we can find a syntax that both accept. This is with gcc-4.5 and Visual Studio 2010
#if defined(__GNUC__)
TGenericBindingHandler<T>::template AddBinding<ContainerClass>(spec, N, &ContainerClass::template SingleBindMemberStruct<T,N>::m_Member);
#else
TGenericBindingHandler<T>::template AddBinding<ContainerClass>(spec, N, &ContainerClass::SingleBindMemberStruct<T,N>::m_Member);
#endif
}
};
有没有人在语法上知道::template
可以或应该用于什么?如果有人从标准中获得了一个描述它的片段,那将是完美的!
编辑:
好吧所以听起来就像帮助编译器确定什么是模板一样简单,因为这是static
函数,我们使用范围解析运算符而不是点运算符来告诉编译器模板。所以现在唯一剩下的问题是为什么Visual Studio也不需要这个呢?
答案 0 :(得分:2)
它告诉编译器AddBinding
是一个模板 - 因为AddBinding
的定义依赖于T
,所以编译器在其正确的阶段不会知道这一点。编译过程(我不是细节方面的专家,但它与C ++编译模型AFAIK有关)。通过在template
之后编写::
,您可以为编译器提供原本不具备的信息。我更具体地说,它知道它在<
之后看到<
时会处理模板而不是AddBinding
运算符。
如果您想要更详细的答案,可能需要查看C ++模板:完整指南。 (如果您搜索Google,我认为它可以PDF形式提供。)
答案 1 :(得分:1)
AddBinding是一个从属名称,在编译期间不会将其识别为模板。没有template
,它将被解释为函数指针和<
比较,这根本没有意义。