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++ 为什么模板允许未完成类的方法类型?_C++_Templates_Class Method_Incomplete Type - Fatal编程技术网

C++ 为什么模板允许未完成类的方法类型?

C++ 为什么模板允许未完成类的方法类型?,c++,templates,class-method,incomplete-type,C++,Templates,Class Method,Incomplete Type,为什么模板允许您绕过不完整的类型? 我在一本关于节点、链表和迭代器的教科书中学习了一个例子。我注意到他在Iterator类中使用了一个指向列表和节点实例的指针,但随后他还在List类中创建了一个方法来返回该类的迭代器。当我试图自己实现它以节省时间时,我没有对它进行模板化,而是选择了int数据,但是我的迭代器类型的方法会得到一个类型不完整的错误。当我遵循模板符号时,它工作得很好 template<class Datatype> class Object; template<

为什么模板允许您绕过不完整的类型? 我在一本关于节点、链表和迭代器的教科书中学习了一个例子。我注意到他在Iterator类中使用了一个指向列表和节点实例的指针,但随后他还在List类中创建了一个方法来返回该类的迭代器。当我试图自己实现它以节省时间时,我没有对它进行模板化,而是选择了int数据,但是我的迭代器类型的方法会得到一个类型不完整的错误。当我遵循模板符号时,它工作得很好

template<class Datatype> class Object;    
template<class Datatype> class List;
template<class Datatype> class Helper;

template <class Datatype>
class Object {
public:
    Object() : m_data(), next(0) {}
    Datatype m_data;
    Object<Datatype>* next;
};

template <class Datatype>
class List{
public:
    List() : m_head(0), m_tail(0) {}
    Object<Datatype>* m_head;
    Object<Datatype>* m_tail;
    int m_count;
    Helper<Datatype> getHelper()
    {
        return Helper<Datatype>( m_head, this);
    }
};
template <class Datatype>
class Helper {
public:
    Helper( Object<Datatype>* p_node, List<Datatype>* p_list);
    Object<Datatype>* m_node;
    List<Datatype>* m_list;

};
模板类对象;
模板类列表;
模板类助手;
模板
类对象{
公众:
对象():m_data(),下一个(0){}
数据类型m_数据;
对象*下一个;
};
模板
班级名单{
公众:
List():m_head(0),m_tail(0){}
物体*m_头;
对象*m_尾;
国际货币单位计数;
Helper getHelper()
{
返回助手(m_头,此);
}
};
模板
类助手{
公众:
辅助对象(对象*p_节点,列表*p_列表);
对象*m_节点;
列表*m_列表;
};
编辑:我的问题所指的内容可能有些混乱。它指的是类类型的方法

Helper<Datatype> getHelper()
Helper getHelper()

硬输入时,会导致类型不完整的错误。我想知道模板是怎么解决的?我有一些想法,因为模板允许不同类型的内存大小,所以直到编译时它才处理方法内存返回大小。我很好奇这是如何工作的,如果有人能给出答案,我将不胜感激。

在您之前发布的代码中,第1-3行声明了所有类,因此编译器现在可以在看到完整定义之前解析指向这些类的实例的指针

同样的技术也适用于非模板情况

更新OP后编辑: 在非模板类中,要使用实际对象(而不仅仅是指针),需要有完整的类定义。因此,转发声明是不够的,当您试图返回Helper的实例时,它会给您一个错误


在使用模板之前,模板不会被实例化,在您的例子中,模板是在您提供了Helper的完整定义之后实例化的,因此编译器在找到它时没有问题。

我是新来的,花了一点时间才弄明白如何做到这一点。这仅仅是一个基本的功能测试@LuchianGrigoreIs它只是MSVC,让你可以逍遥法外,还是GCC和Clang?它们有不同的实例化机制,MSVC通常允许你做技术上不允许的事情。我只是在测试中使用Xcode,真实的例子来自Ron Penton为游戏程序员提供的数据结构,所以我假设你在大多数情况下都可以逃脱@SebastianRedlI理解转发声明允许指向实例的指针,但我的问题涉及实际的实例方法:Helper getHelper(),该方法在List类中使用,当非模板化时,它会给出一个类型不完整的错误—将模板视为复杂的宏(这实际上是非常错误的,但这是一个很好的类比)。您在某一点编写宏,然后使用它(实例化模板)在另一点上。实际编译是在使用宏时进行的。定义宏时知道或不知道什么并不重要。检查是在使用宏时进行的,此时编译器有足够的信息通过检查。