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++ GCC模板问题_C++_Templates_Gcc - Fatal编程技术网

C++ GCC模板问题

C++ GCC模板问题,c++,templates,gcc,C++,Templates,Gcc,VisualStudio可以很好地编译这段代码,但gcc只允许它在没有模板操作符的情况下编译。使用模板运算符时,会出现以下错误: 第29行:错误:应为“;”在“itrValue”之前 类测试 { 公众: Test&operatorGCC是正确的,const_iterator是一种类型,模板操作符中的模板依赖于@Pieter answer,这是正确的,关于模板如何处理的更多信息。 首先,模板只有在实例化时才被编译,因此如果您没有为给定类型实例化模板,那么代码将永远不会被编译 现在,当您实例化模板时

VisualStudio可以很好地编译这段代码,但gcc只允许它在没有模板操作符的情况下编译。使用模板运算符时,会出现以下错误:

第29行:错误:应为“;”在“itrValue”之前

类测试
{
公众:

Test&operatorGCC是正确的,const_iterator是一种类型,模板操作符中的模板依赖于@Pieter answer,这是正确的,关于模板如何处理的更多信息。 首先,模板只有在实例化时才被编译,因此如果您没有为给定类型实例化模板,那么代码将永远不会被编译

现在,当您实例化模板时,有两个步骤验证模板代码。首先,无论实例化类型是什么,都要验证模板的正确性。要使用更简单易懂的示例进行检查:

#include "a.h"

template <typename T> void f( T const & )
{
   T::type x;     // is T::type a type?
};

int main()
{
   A a;
   f( a );
}
在第一种情况下,类型确实是一种类型,而在第二种情况下则不是。现在的标准规定,如果它确实是一种类型,那么模板的程序员必须声明它,以便用上面的语法通知编译器:

template <typename T> void f( T const & a )
{
    typename T::type x; // define a variable x of type T::type
}
模板空f(T常量和a)
{
typename T::type x;//定义一个T::type类型的变量x
}
现在,为了完成处理,编译器必须检查模板代码本身是否正确,并且当使用特定类型T实例化模板代码时,它是否也正确。这是编译器在验证的第二阶段执行的操作。它应用该类型并重新检查错误

在您的情况下,它更具争议性,因为每个人(除了编译器)知道std::list::const_迭代器是任何给定T的类型。当然,它不需要是。从语言的角度来看,某些代码可以为特定数据类型T提供与常规列表模板不同的模板专用化。编译器不知道是否可以这样


请注意,在std名称空间中专门化一个模板是非常错误的,因为它会像重新定义迭代器类型一样改变行为。但是编译器将std名称空间视为任何其他名称空间,并将其列为任何其他模板类。

我认为有必要告诉您其他消除歧义的方法de>typename
我已经回答了另一个问题

另一个是模板,看这里:

template<typename T>
struct some {
    template<int V>
    struct other {
        typedef int type;
        static const int value = V;
    };
};

template<typename V>
void doit() {
    typename some<V>::template other<42>::type * int_pointer;
}
模板
构造一些{
模板
结构其他{
typedef int类型;
静态常数int值=V;
};
};
模板
void doit(){
typename some::template other::type*int\u指针;
}
注意我们如何使用模板和类型名消除歧义

您访问的名为
::type
的对象确实是一个类型。不要进行乘法运算,否则会错误地认为
::type
是一个静态值(整数或其他值)

模板告诉编译器


other
是与
42
参数一起使用的模板。它不是使用
运算符>
运算符的比较即使答案已经由Pieter提供,在讨论编译器行为时,重要的是定义编译器的精确版本,因为不同版本具有不同的行为rs(g++4.0确实抱怨了很多事情)是的。对于新手来说,这并不总是显而易见的……但这与访问静态变量时使用的语法相同。
typename
让编译器知道你在追求什么。是的,有趣的是,GCC有这个功能(发现const_迭代器是一种类型)在VisualStudio之前和之后决定删除该功能,以便在GCC上编译的代码更可能符合该标准。
struct A { // version 1
    typedef int type;
};

struct A { // version 2
    static std::string type;
};
std::string A::type = "A";
template <typename T> void f( T const & a )
{
    typename T::type x; // define a variable x of type T::type
}
template<typename T>
struct some {
    template<int V>
    struct other {
        typedef int type;
        static const int value = V;
    };
};

template<typename V>
void doit() {
    typename some<V>::template other<42>::type * int_pointer;
}