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 - Fatal编程技术网

C++ 嵌套类包含头

C++ 嵌套类包含头,c++,templates,C++,Templates,我有一个类似这样的类: // List.hpp template<typename T> class List { ... private: class Node; }; //List.hpp 模板 班级名单{ ... 私人: 类节点; }; 我想把List::Node的完整定义放在一个单独的文件中: // Node.hpp template<typename T> class List<T>::Node { ... }; //N

我有一个类似这样的类:

// List.hpp
template<typename T>
class List {
    ...
private:
    class Node;
};
//List.hpp
模板
班级名单{
...
私人:
类节点;
};
我想把
List::Node
的完整定义放在一个单独的文件中:

// Node.hpp
template<typename T>
class List<T>::Node {
    ...
};
//Node.hpp
模板
类列表::节点{
...
};
我的问题是,我应该在每个文件中包含什么,以及将
#include
放在哪里

最简单的方法(我认为)是在
List.hpp
的末尾包含
Node.hpp
,而不在
Node.hpp
中包含任何内容。但是,这使得
Node.hpp
本身不是一个完整的文件(比如说,如果我在IDE或其他地方打开它,由于缺少
List
的定义,会有很多错误)。此外,我不确定是否可以将
#include
放在文件底部


假设每个文件都有自己的include guard
#define
,我还可以在
节点.hpp
的顶部包含
列表.hpp
(使IDE满意),然后在
列表.hpp
的底部再次包含
节点.hpp
,但是我不知道这是否是个好主意。

在编译
List::Node
的成员函数时,编译器将始终需要模板类
List
的可见性。因此,任何需要查看
Node.hpp
内容的编译单元都需要查看
List.hpp
的内容(模板成员的定义)

最简单的选择是将
节点.hpp
的内容放在
列表.hpp
的末尾,并且只有
#在需要任何一个模板的编译单元中包含“List.h”
。这样就完全不需要
Node.hpp

如果您确实必须同时拥有这两个标题(对我来说,这似乎是任意的、毫无意义的,因为
List::Node
List
的一个组件),那么一个选项就是帮助使用include-guard

  // List.hpp

  #ifndef LIST_HPP_INCLUDED   // some unique macro
  #define LIST_HPP_INCLUDED

  // definition of templated class List

  #include "Node.hpp"   // this must be after the definition of List<T>
  #endif
//List.hpp
#ifndef列表\u HPP\u包含//一些独特的宏
#定义包含的水电站清单
//模板化类列表的定义
#包括“Node.hpp”//这必须在列表的定义之后
#恩迪夫
在Node.hpp中

  // Node.hpp

  #ifndef NODE_HPP_INCLUDED   // some unique macro
  #define NODE_HPP_INCLUDED

  #include "List.hpp"     // this must precede the definitions for List<T>::Node

  // definition of templated class List<T>::Node

  #endif
//Node.hpp
#ifndef NODE\u HPP\u包含//一些独特的宏
#定义包含的节点\u水电站\u
#包括“List.hpp”//这必须在List::Node的定义之前
//模板化类列表::节点的定义
#恩迪夫
这允许任何编译单元将其中一个头设置为
#include
d,并且include保护停止无限递归include


大多数现代IDE都能解决这个问题。如果你有一个没有,那么只需转换到一个头文件。

回答你的部分问题:你可以把
#incldue
放在你想放的任何地方,我看不到,它会如何帮助你,如果您两次包含同一个文件,您可以按照您的建议执行--您也可以根据需要有选择地将其包含在其他.h或.cpp文件中。这可以将更改node.hpp的编译爆炸半径减少到实际使用它的位置,而不是包括list.hppalso的所有内容。下面是一个这种安排的实例:semi offtopic:如果我在一个.h文件中有很多模板化的代码,并且这些代码变化很大,我经常将它从filename.h移到filename_impl.h,然后只将它包含在实际使用该模板方法的.cpp文件中。当他们只需要类型信息而不需要实现细节时,它会阻止大部分项目检测到更改和重建。如果您错过了一个点,编译器会给出一个非常好的链接错误,告诉您要包含_impl.@MikeMB…如果您包含同一个文件两次。拥有
Node.hpp
include
List.hpp
在它的顶部使
Node.hpp
本身成为一个完整的编译单元。我想把
Node
分离到它自己的文件中,只是为了使
List.hpp
更干净,但正如你所说的,这是没有必要的。另外,如果我按照你的建议做(把
class List::Node{…}
List.hpp
的末尾,我能不能直接在
列表中定义
节点
<代码>节点
列表
的嵌套类。任何嵌套类的定义(模板化或非模板化)都可以放在包含类的定义中。