[indirect.general] # 20 Memory management library [[mem]](./#mem) ## 20.4 Types for composite class design [[mem.composite.types]](mem.composite.types#indirect.general) ### 20.4.1 Class template indirect [[indirect]](indirect#general) #### 20.4.1.1 General [indirect.general] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5901) An indirect object manages the lifetime of an owned object[.](#1.sentence-1) An indirect object is[*valueless*](#def:valueless,indirect_object "20.4.1.1 General [indirect.general]") if it has no owned object[.](#1.sentence-2) An indirect object may become valueless only after it has been moved from[.](#1.sentence-3) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5907) In every specialization indirect, 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 indirect 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#L5916) Constructing an owned object with args... using the allocator a means callingallocator_traits​::​construct(a, *p*, args...) whereargs is an expression pack,a is an allocator, and*p* is a pointer obtained by calling allocator_traits​::​allocate[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5925) The member *alloc* is used for any memory allocation and element construction performed by member functions during the lifetime of each indirect object[.](#4.sentence-1) The allocator *alloc* 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 indirect operation[.](#4.sentence-3) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5948) A program that instantiates the definition of the template indirect with a type for the T parameter that is 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#L5959) The template parameter T of indirect may be an incomplete type[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5963) The template parameter Allocator of indirect shall meet the *Cpp17Allocator* requirements[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5967) If a program declares an explicit or partial specialization of indirect, the behavior is undefined[.](#8.sentence-1)