[polymorphic.general] # 20 Memory management library [[mem]](./#mem) ## 20.4 Types for composite class design [[mem.composite.types]](mem.composite.types#polymorphic.general) ### 20.4.2 Class template polymorphic [[polymorphic]](polymorphic#general) #### 20.4.2.1 General [polymorphic.general] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6758) A polymorphic object manages the lifetime of an owned object[.](#1.sentence-1) A polymorphic object may own objects of different types at different points in its lifetime[.](#1.sentence-2) A polymorphic object is[*valueless*](#def:valueless,polymorphic_object "20.4.2.1 General [polymorphic.general]") if it has no owned object[.](#1.sentence-3) A polymorphic object may become valueless only after it has been moved from[.](#1.sentence-4) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6767) In every specialization polymorphic, if the type allocator_traits​::​value_type is not the same type as T, the program is ill-formed[.](#2.sentence-1) Every object of type polymorphic uses an object of type Allocator to allocate and free storage for the owned object as needed[.](#2.sentence-2) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6775) Constructing an owned object of type U with args... using the allocator a means callingallocator_traits​::​construct(a, *p*, args...) whereargs is an expression pack,a is an allocator, and*p* points to storage suitable for an owned object of type U[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6783) The member *alloc* is used for any memory allocation and element construction performed by member functions during the lifetime of each polymorphic value object, or until the allocator is replaced[.](#4.sentence-1) The allocator may be replaced only via assignment or swap()[.](#4.sentence-2) Allocator replacement is performed by copy assignment, move assignment, or swapping of the allocator only if ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")): - [(4.1)](#4.1) allocator_traits​::​propagate_on_container_copy_assignment​::​value, or - [(4.2)](#4.2) allocator_traits​::​propagate_on_container_move_assignment​::​value, or - [(4.3)](#4.3) allocator_traits​::​propagate_on_container_swap​::​value is true within the implementation of the corresponding polymorphic operation[.](#4.sentence-3) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6807) A program that instantiates the definition of polymorphic for a non-object type, an array type,in_place_t, a specialization of in_place_type_t, or a cv-qualified type is ill-formed[.](#5.sentence-1) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6816) The template parameter T of polymorphic may be an incomplete type[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6820) The template parameter Allocator of polymorphic shall meet the requirements of *Cpp17Allocator*[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6824) If a program declares an explicit or partial specialization of polymorphic, the behavior is undefined[.](#8.sentence-1)