Iceman
Iceman

Reputation: 397

Error "C2027 use of undefined type" when use std::deque instead of vector

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

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

If to define _childs as std::vector<XMLNode> the code will compile, but with std::deque I'm getting error:

C2027 use of undefined type

What is wrong with std::deque here and how to fix it?

Upvotes: 1

Views: 1644

Answers (2)

songyuanyao
songyuanyao

Reputation: 172924

Since C++17, std::vector (with std::allocator as the allocator) could be instantiated with incomplete types. [vector.overview]/4:

An incomplete type T may be used when instantiating vector if the allocator meets the allocator completeness requirements. T shall be complete before any member of the resulting specialization of vector is referenced.

And std::allocator does meet the allocator completeness requirements. [default.allocator]/1

All specializations of the default allocator meet the allocator completeness requirements ([allocator.requirements.completeness]).

On the other hand, std::deque doesn't have such guarantee; it's allowed only for std::forward_list, std::list and std::vector.

Upvotes: 4

Max Vollmer
Max Vollmer

Reputation: 8598

Why does std::deque fail

std::deque needs a complete element type. At the point of your declaration XMLNode is still incomplete. The usual way around this is to use some kind of (smart) pointer. Pointers to incomplete types are complete. (All pointers have the same size, no matter what they point to.)

So one option would be std::deque<std::unique_ptr<XMLNode>>, however depending on your scenario you might want to work with something else.

See docs for std::deque

Why does std::vector compile

std::vector allows an incomplete element type during instantiation since C++17 under special circumstances. Specifically, it allows it when the allocator for the incomplete type is complete. That seems to be the case in your example. Please note that any usage of the std::vector can only be done when the element type is complete, e.g. adding, resizing, accessing elements etc.

See docs for std::vector

Upvotes: 1

Related Questions