使用std :: deque代替vector时出现错误“ C2027使用未定义类型”

时间:2019-12-15 10:56:55

标签: c++

#include <string>
#include <deque>
//#include <vector>
#include <map>

namespace xmltree {
    class XMLNode {
        // other fields, methods...
        std::deque<XMLNode> _childs;
...

如果将_childs定义为std::vector<XMLNode>,则将编译代码,但是使用std::deque时会出错:

  

C2027使用未定义类型

std :: deque在这里出了什么问题以及如何解决?

2 个答案:

答案 0 :(得分:4)

自C ++ 17起,std::vector(使用std::allocator作为分配器)可以使用不完整的类型实例化。 [vector.overview]/4

  

如果分配器满足allocator completeness requirements,则在实例化T时可以使用不完整的类型vector。在引用T所产生的专业化的任何成员之前,vector应该是完整的。

std::allocator确实满足分配器完整性要求。 [default.allocator]/1

  

默认分配器的所有专业化都满足分配器完整性要求([allocator.requirements.completeness])。

另一方面,std::deque没有这样的保证;只能用于std::forward_liststd::liststd::vector

答案 1 :(得分:1)

std::deque为什么失败

std::deque需要完整的元素类型。在您声明时,XMLNode仍不完整。解决此问题的常用方法是使用某种(智能)指针。指向不完整类型的指针是完整的。 (无论它们指向什么,所有指针的大小都相同。)

因此,一个选项是std::deque<std::unique_ptr<XMLNode>>,但是根据您的情况,您可能希望使用其他选项。

请参见docs for std::deque

std::vector为何编译

std::vector在实例化期间允许使用不完整的元素类型,因为C ++ 17在特殊情况下。具体来说,当不完整类型的分配器完成时,它允许它。在您的示例中似乎就是这种情况。请注意,std::vector的任何用法都只能在元素类型完整时才能完成,例如添加,调整大小,访问元素等。

请参见docs for std::vector