C++ ::template除了使TMP编译之外还有什么意义
可能重复:C++ ::template除了使TMP编译之外还有什么意义,c++,templates,syntax,C++,Templates,Syntax,可能重复: 下面是一些模板化程度很高的容器类的代码片段,这些容器类用于绑定任意数量的任意类型的字段。我的一位同事发现我的代码没有在GCC下编译,经过大量研究后,他找到了修复方法,通过添加::template,使其正确推断模板。。。我们两人以前都没有看到过这一点,现在仍然不知道这是什么,除了GCC需要我的代码,VisualStudio2010不需要 template< typename T, int N > struct SingleBindMemberStruct
下面是一些模板化程度很高的容器类的代码片段,这些容器类用于绑定任意数量的任意类型的字段。我的一位同事发现我的代码没有在GCC下编译,经过大量研究后,他找到了修复方法,通过添加
::template
,使其正确推断模板。。。我们两人以前都没有看到过这一点,现在仍然不知道这是什么,除了GCC需要我的代码,VisualStudio2010不需要
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
}
};
模板
结构SingleBindMemberStruct
{
typedef typename TGenericBindingHandler::BindToUse BindType;
BindType m_成员;
模板
静态void AddBinding(CPackedTableDataSpec*规范)
{
//也许在较新版本的编译器中,我们可以找到一种既能接受又能接受的语法,这就是gcc-4.5和VisualStudio2010
#如果已定义(_GNUC__)
TGenericBindingHandler::template AddBinding(spec、N和ContainerClass::template SingleBindingMemberStruct::m_成员);
#否则
TGenericBindingHandler::模板AddBinding(spec、N和ContainerClass::SingleBindingMemberStruct::m_成员);
#恩迪夫
}
};
是否有人从语法上知道::template
可以或应该用于什么?如果有人有一个标准的片段来描述它,那将是完美的
编辑:
好的,听起来就像帮助编译器确定什么是模板一样简单,因为这是一个
静态
函数,我们使用范围解析操作符而不是点操作符来告诉编译器模板。所以现在剩下的唯一问题是为什么Visual Studio也不需要它?它告诉编译器,AddBinding
是一个模板——因为AddBinding
的定义依赖于T
,否则编译器在编译过程的正确阶段不会知道这一点(我不是专家的细节,但它是与C++编译模型AFIK)。通过在::
之后编写模板
,您可以为编译器提供它本来无法获得的信息。我想更具体地说,它知道它正在处理一个模板,而不是一个AddBinding是一个依赖名称,它在编译过程中不会被识别为模板。没有模板
,它将被解释作为函数指针和实际上,我认为它告诉编译器,容器类
是一个模板参数,因为#if
的两个分支都在AddBinding
上使用它。请看:@Chris:在这种情况下肯定是一样的吗?ifAddBinding
(即嵌套在TGenericBindingHandler
中的模板)是一个模板,那么容器类
显然是相应的模板参数。或者我缺少一个细微的区别吗?@Stuart我同意标准要求::template
同时在AddBinding
和容器类
上。然而,单纯地看代码,区别只是存在ts在AddBinding
的第三个参数中。AddBinding是一个具有模板返回类型的静态模板函数,并使用此模板对象的模板定义参数。听起来很可怕,但工作起来有点像带有别名的std::tuple
。现在,如果我支持可变模板,我就不需要那么多的typedefs和默认的模板参数。@Chris:我没有注意到在代码的右边还有另一个::template
(因为行没有包装,所以对我来说它不在屏幕上)。它不是“只是让它编译”。它消除了歧义。无论你是否有:::template,你都可以编写编译的代码,并将产生不同的结果。我不相信这与上述问题完全相同-就我个人而言,如果我有3000多名代表,我会投票重新开放:)部分原因是我怀疑Johannes对这个问题的回答可能比已经给出的更好…基本上,链接的问题回答了需要它的原因,所以这是我的问题的一半。另一半只是好奇为什么Visual Studio不需要它,以及标准对模板pa的编译器解释有什么规定rsing使两个编译器都正确(或不正确)。