1. US NB comment 9
The new notion of "replaceable types" (6.9.1) is confusingly similar to the existing notions of "transparently replaceable objects" (6.8.4) and "replaceable functions", such as replaceable allocation functions (9.6.5) and replaceable contract-violation handlers (6.11.3).
The new notion of "replaceable" is not used by any C++26 library machinery. Therefore it does not need to exist in C++26. The proposed change is entirely removal of various terms of art all of which are dangling loose ends. The removal of this type trait has no effect on the rest of C++.
There are 88 instances of the string "
" in the Committee Draft.
Adopting the proposed change will remove 36 instances concerned with
, leaving:
-
13 instances concerned with "system_context_replaceability"
-
4 concerned with "transparently replaceable"
-
35 instances concerned with replaceable functions
2. Important note
We needn’t touch anything not listed below. Literally nothing in the Standard depends on this inutile notion.
3. Proposed wording
The wording in this section is relative to the Committee Draft of C++26, [N5013].
3.1. [basic.types.general]
Modify [basic.types.general] as follows:
9․ Arithmetic types ([basic.fundamental]), enumeration types, pointer types, pointer-to-member types ([basic.compound]),, and cv-qualified versions of these types are collectively called scalar types. Scalar types, trivially copyable class types ([class.prop]), arrays of such types, and cv-qualified versions of these types are collectively called trivially copyable types. Scalar types, trivially relocatable class types ([class.prop]), arrays of such types, and cv-qualified versions of these types are collectively called trivially relocatable types.
std :: nullptr_t Cv-unqualified scalar types, replaceable class types ([class.prop]), and arrays of such types are collectively called replaceable types.Scalar types, standard-layout class types ([class.prop]), arrays of such types, and cv-qualified versions of these types are collectively called standard-layout types. Scalar types, implicit-lifetime class types ([class.prop]), array types, and cv-qualified versions of these types are collectively called implicit-lifetime types.10․ A type is a literal type if it is: [...]
3.2. [class.pre]
Modify [class.pre] as follows:
class-property-specifier:
final
trivially_relocatable_if_eligible
replaceable_if_eligible [...]
5․ Each class-property-specifier shall appear at most once within a single class-property-specifier-seq. Whenever a class-key is followed by a class-head-name, the identifier
final ,or,
trivially_relocatable_if_eligible orand a colon or left brace, the identifier is interpreted as a class-property-specifier.,
replaceable_if_eligible [Example:
—end example]struct A ; struct A final {}; // OK, definition of struct A, // not value-initialization of variable final
struct X { struct C { constexpr operator int () { return 5 ; } }; struct B trivially_relocatable_if_eligible : C {}; // OK, definition of nested class B, // not declaration of a bit-field member // trivially_relocatable_if_eligible };
3.3. [class.prop]
Modify [class.prop] as follows:
[...]
4․ A class
is a trivially relocatable class if it is eligible for trivial relocation and
C
has the
class-property-specifier,
trivially_relocatable_if_eligible is a union with no user-declared special member functions, or
is default-movable.
5․ [Note: A class with const-qualified or reference non-static data members can be trivially relocatable. —end note]
6․ A classis eligible for replacement unless
C
it has a base class that is not a replaceable class,it has a non-static data member that is not of a replaceable type,overload resolution fails or selects a deleted constructor when direct-initializing an object of typefrom an xvalue of type
C ([dcl.init.general]),
C overload resolution fails or selects a deleted assignment operator function when assigning to an lvalue of typefrom an xvalue of type
C ([expr.assign], [over.assign])), or
C it has a deleted destructor.
7․ A classis a replaceable class if it is eligible for replacement and
C
has theclass-property-specifier,
replaceable_if_eligible is a union with no user-declared special member functions, oris default-movable.8․ [Note: Accessibility of the special member functions is not considered when establishing trivial relocatability
or replaceability. —end note]9․ [Note: Not all trivially copyable classes are trivially relocatable
or replaceable. —end note]10․ A class
is a standard-layout class if it: [...]
S
3.4. [diff.cpp23.dcl.dcl]
Modify [diff.cpp23.dcl.dcl] as follows:
1. Affected subclause: [dcl.decl.general]
Change: Introduction of
trivially_relocatable_if_eligible andas
replaceable_if_eligible identifiersan identifier with special meaning.
Rationale: Support declaration of trivially relocatableand replaceabletypes.
Effect on original feature: Valid C++ 2023 code can become ill-formed.
[Example:
struct C {}; struct C replaceable_if_eligible trivially_relocatable_if_eligible {}; // was well-formed (new variable replaceable_if_eligible trivially_relocatable_if_eligible ) // now ill-formed (redefines C) —end example]
3.5. [diff.cpp23.library]
Note: This clause should point to [cpp.replace.general], not [res.on.macro.definitions]; that is the subject of US NB comment 57.
Modify [diff.cpp23.library] as follows:
2. Affected subclause: [res.on.macro.definitions]
Change: Additional restrictions on macro names.
Rationale: Avoid hard to diagnose or non-portable constructs.
Effect on original feature: Names of special identifiers may not be used as macro names. Valid C++ 2023 code that definesa macro namedor
replaceable_if_eligible as macros
trivially_relocatable_if_eligible is invalid in this revision of C++.
trivially_relocatable_if_eligible
3.6. [expr.prim.lambda.closure]
Modify [expr.prim.lambda.closure] as follows:
3. The closure type is not an aggregate type ([dcl.init.aggr]); it is a structural type ([temp.param]) if and only if the lambda has no lambda-capture. An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:
the size and/or alignment of the closure type,
whether the closure type is trivially copyable ([class.prop]),
whether the closure type is trivially relocatable ([class.prop]),
whether the closure type is replaceable ([class.prop]),orwhether the closure type is a standard-layout class ([class.prop]).
An implementation shall not add members of rvalue reference type to the closure type.
3.7. [lex.name]
Modify [lex.name] as follows:
2. The identifiers in Table 4 have a special meaning when appearing in a certain context. When referred to in the grammar, these identifiers are used explicitly rather than using the identifier grammar production. Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier.
Table 4 — Identifiers with special meaning
final import post replaceable_if_eligible override module pre trivially_relocatable_if_eligible
3.8. [library.class.props]
Modify [library.class.props] as follows:
1. Unless explicitly stated otherwise, it is unspecified whether any class described in [support] through [exec] and [depr] is a trivially copyable class, a standard-layout class, or an implicit-lifetime class ([class.prop]).
2. Unless explicitly stated otherwise, it is unspecified whether any class for which trivial relocation (i.e., the effects of
([obj.lifetime])) would be semantically equivalent to move-construction of the destination object followed by destruction of the source object is a trivially relocatable class ([class.prop]).
trivially_relocate
3. Unless explicitly stated otherwise, it is unspecified whether a classis a replaceable class ([class.prop]) if assigning an xvalue
C of type
a to an object
C of type
b is semantically equivalent to destroying
C and then constructing from
b in
a ’s place.
b
3.9. [meta.reflection.traits]
Modify [meta.reflection.traits] as follows:
[...] consteval bool is_trivially_copyable_type ( info type ); consteval bool is_trivially_relocatable_type ( info type ); consteval bool is_replaceable_type ( info type ); consteval bool is_standard_layout_type ( info type ); [...]
3.10. [meta.syn]
Modify [meta.syn] as follows:
[...] consteval bool is_trivially_copyable_type ( info type ); consteval bool is_trivially_relocatable_type ( info type ); consteval bool is_replaceable_type ( info type ); consteval bool is_standard_layout_type ( info type ); [...]
3.11. [meta.type.synop]
Modify [meta.type.synop] as follows:
[...] template < class T > struct is_trivially_copyable ; template < class T > struct is_trivially_relocatable ; template < class T > struct is_replaceable ; template < class T > struct is_standard_layout ; [...] template < class T > constexpr bool is_implicit_lifetime_v = is_implicit_lifetime < T >:: value ; template < class T > constexpr bool is_replaceable_v = is_replaceable < T >:: value ; template < class T > constexpr bool has_virtual_destructor_v = has_virtual_destructor < T >:: value ;
3.12. [meta.unary.prop]
Modify Table 54 in [meta.unary.prop] as follows:
Template Condition Preconditions
template < class T > struct is_trivially_copyable ; is a trivially copyable type ([basic.types.general])
T shall be a complete type or cv
remove_all_extents_t < T > .
void
template < class T > struct is_trivially_relocatable ; is a trivially relocatable type ([basic.types.general])
T shall be a complete type or cv
remove_all_extents_t < T > .
void
template < class T > struct is_replaceable ; is a replaceable type ([basic.types.general])
T shall be a complete type or cv
remove_all_extents_t < T > .
void
template < class T > struct is_standard_layout ; is a standard-layout type ([basic.types.general])
T shall be a complete type or cv
remove_all_extents_t < T > .
void