Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
450 views
in Technique[技术] by (71.8m points)

c++ - Why does std::vector work with incomplete types in class definitions?

The following question came up:

The c++ standard seems to say, that std::vector requires a complete type to work. (See https://en.cppreference.com/w/cpp/container/vector ) Then, why does the following code still compile?

#include <vector>

struct parent;

struct child
{
    std::vector<parent> parents; //parent is incomplete here!
};

struct parent
{
    std::vector<child> children;
};

This seems counterintuitive. If std::vector requires a complete type, then std::vector<parent> should not compile because only its forward declaration is known inside the class definition of child.

  • Is this behaviour something special about class definitions?
  • Did I get it wrong, and std::vector does not require a complete type?
  • Or, is this just a fluke? In that technically this isn't allowed, but it works for all implementations anyways...

EDIT

There seems to be a difference between c++11 and c++17. I would like to understand the c++11 version.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Standard says (draft N3690; this is post C++11, pre C++14):

[res.on.functions]

1 In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++standard library depends on components supplied by a C++program. If these components do not meet their requirements, the Standard places no requirements on the implementation.

2 In particular, the effects are undefined in the following cases:

— if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

Given that standard places no requirements, and effects are undefined (as far as I can tell, this is same as undefined behaviour), there is no expectation for the instantiation to "not work" any more than there is expectation for it to (appear to) "work".


Since C++17, the requirement was relaxed and std::vector does not require the value type to be complete, if used with appropriate allocator (the default allocator is appropriate). (This freedom does not extend to using all member functions; they have additional requirements).

Standard quote (current draft):

[vector.overview]

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.

[allocator.requirements.completeness]

If X is an allocator class for type T, X additionally meets the allocator completeness requirements if, whether or not T is a complete type:

  • X is a complete type, and
  • all the member types of allocator_-traits other than value_-type are complete types.

[default.allocator]

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...