Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ ::template除了使TMP编译之外还有什么意义_C++_Templates_Syntax - Fatal编程技术网

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:在这种情况下肯定是一样的吗?if
AddBinding
(即嵌套在
TGenericBindingHandler
中的模板)是一个模板,那么
容器类
显然是相应的模板参数。或者我缺少一个细微的区别吗?@Stuart我同意标准要求
::template
同时在
AddBinding
容器类
上。然而,单纯地看代码,区别只是存在ts在
AddBinding
的第三个参数中。AddBinding是一个具有模板返回类型的静态模板函数,并使用此模板对象的模板定义参数。听起来很可怕,但工作起来有点像带有别名的
std::tuple
。现在,如果我支持可变模板,我就不需要那么多的typedefs和默认的模板参数。@Chris:我没有注意到在代码的右边还有另一个
::template
(因为行没有包装,所以对我来说它不在屏幕上)。它不是“只是让它编译”。它消除了歧义。无论你是否有:::template,你都可以编写编译的代码,并将产生不同的结果。我不相信这与上述问题完全相同-就我个人而言,如果我有3000多名代表,我会投票重新开放:)部分原因是我怀疑Johannes对这个问题的回答可能比已经给出的更好…基本上,链接的问题回答了需要它的原因,所以这是我的问题的一半。另一半只是好奇为什么Visual Studio不需要它,以及标准对模板pa的编译器解释有什么规定rsing使两个编译器都正确(或不正确)。